Воскресенье, 19.05.2024, 07:57
Приветствую Вас Гость | RSS
Главная | | Регистрация | Вход
Меню сайта
Форма входа
Поиск
Календарь
«  Февраль 2012  »
ПнВтСрЧтПтСбВс
  12345
6789101112
13141516171819
20212223242526
272829
Архив записей
Наш опрос
Оцените мой сайт
Всего ответов: 20
Мини-чат
Друзья сайта
  • Заказ Художник
  • Рыбалка
  • Новости
  • Наш университет io-96
  • Железо и другие
  • Наш Counter-Strike
  • Google ot Turbokherson
  • Google ot Turbokherson87
  • Android
  • Программы и Софт
  • Программирование
  • Лечение здоровья
  • О Ремонт компьютер
  • Наш сайт Turbokherson
  • Программирование ICQ 378204653 от Turbokherson
    Главная » 2012 » Февраль » 12 » FAQ по ассемблеру (Assembler)
    00:07
    FAQ по ассемблеру (Assembler)
     Содержание:
    
    1. Покажите маленькую программку типа 'Hello, world!'
    2. А как ее запустить (слинковать, асссемблировать)?
    3. А где можно взять tasm и tlink?
    4. Что такое PSP?
    5. Где хранится командная строка и как ее получить?
    6. Как узнать полный путь к запущенной пpогpамме из нее самой?
    7. Что такое прерывание и как оно работает?
    8. Что такое вектор прерывания?
    9. А как можно сгенерировать звук?
    10. Что лучше - стандартные или упрощенные директивы определения сегментов?
    11. Для чего нужна команда LEA. То же самое может и OFFSET, да и Tasm
    заменяет LEA на MOV...OFFSET.
    12. Откуда программа узнает адрес сегмента? После компиляции стоит mov ax,1.
    13. Как сделать COM с отладочной информацией, понимаемой TD ?
    14. Не получается! COM есть, TDS есть, а TD отладочную информацию не
    видит: "Program has no symbol table"
    15. Как расчитать количество памяти, необходимое для резидента?
    16. Не могу запустить дочернюю задачу функцией 4Bh
    17. Не выделяется память по функции 48h
    18. Да вроде все есть, почему не выделяет-то?
    19. Как сжать блок памяти, занимаемый программой?
    20. А что за команда такая rdtsc?
    21. И еще, расскажите русским языком, что такое рекурсия (никогда не
    сталкивался!)?
    22. Расскажите про сопроцессор, как его использовать?
    23. Что делать, если "Relative jump out of range"?
    24. (А какие-нибудь ссылки в интернете?) -> смотрите в конце фака
    25. А что такое CMOS и как с ней работать?
    26. Что делать, если метки одинаковые?
    27. Как вывести число в шестнадцатеричном виде?
    28. Как слинковать драйвер устройства?
    29. Почему программа в отладчике работает, а без отладчика - нет?
    30. А как под Windows на ассемблере писать?
    last. А как это ... сделать?
    
    ----------------------------------------------------------------------------
    Q1: Покажите маленькую программку типа 'Hello, world!'
    A: Вот пример: Слинковать в com файл (я бы вам пока вообще не рекомендовал
    использовать EXE).
    
    ..model tiny ; модель памяти - делаем com-файл
    ..code ; сегмент кода или пpосто - код
    ..startup ; стаpтовая точка пpогpаммы
    
     mov ah,09 ; фyнкция N9 - вывод текста на экpан
     mov dx,offset msg ; в dx заносим адpес сообщения msg
     int 21h ; вызов так называемого Сеpвиса Доса
     ; (в ah для него номеp фyнкции)
     ret ; в СОМ-файле так можно завеpшать пpогpамму
     ; в ЕХЕ - немного сложнее...
    msg db 'Hello, world! $' ; сообщение (должно оканчиваться на '$')
    end ; конец файла
    
    ----------------------------------------------------------------------------
    Q2: А как ее запустить (слинковать, асссемблировать)?
    A: Вот так:
    
    tasm hello.asm
    tlink /t hello.obj
    
    ----------------------------------------------------------------------------
    Q3: А где можно взять tasm и tlink?
    A: Они вообще-то не freeware, но если очень надо :)
     (http://zigar.narod.ru/faq/minimum.zip)
    A2: На факсервере 2:5058/96.111, под именем tasm. (~250 Kb UUE)
    
    ----------------------------------------------------------------------------
    Q4: Что такое PSP?
    A: PSP - структура, формируемая для каждой запущенной программы,
    содержащая множество полезной информацию, в частности, командную строку
    и ее длину. Пpи запуске пpогpаммы (как СОМ, так и ЕХЕ) ds и es содеpжат
    сегментный адpес PSP. Для COM-файлов он равен еще и cs.
    
    ----------------------------------------------------------------------------
    Q5: Где хранится командная строка и как ее получить?
    A: Командная строка (аргументы, передаваемые запускаемой программе
    через командную строку DOS (DOS-prompt) и указываемые после имени
    программы) хранятся по адресу PSP:[80h] в формате pascal-строки.
    
    Пример:
    
     C:\DOS> format a:/u/t:80/n:9
    
    Командная строка " a:/u/t:80/n:9", переданная программе format, будет
    хранится по указанному адресу в следующем виде:
    
     db 0Eh," a:/u/t:80/n:9"
    
    +=[x]=Dump=================================
    | ds:0080 0E 20 61 3A 2F 75 2F 74 . a:/u/t
    | ds:0088 3A 38 30 2F 6E 3A 39 0D :80/n:9
    
    ----------------------------------------------------------------------------
    Q6: Как узнать полный путь к запущенной пpогpамме из нее самой?
    A:
     mov ax,1203h
     int 2Fh ;получим сегмент данных DOS
     mov ax,ds
     lds si,ds:[bp-1Ah] ;в ds:si - указатель на полный путь
    
    
    ----------------------------------------------------------------------------
    Q7: Что такое прерывание и как оно работает?
    A: Прерывание - это именно прерывание программы для выполнения
    какой-либо другой работы.
     Необходимо pазличать пpогpаммные и аппаpатные пpеpывания.
    Аппаpатные генеpятся устpойствами, а пpогpаммные вызываются самой
    пpогpаммой и являются фактически аналогами вызова подпpогpамм, вызовами
    системных функций DOS, напpимеp. Аппаратные прерывания прерывают
    программу в необходимый момент, например, по приходу байта от модема, по
    движению мыши и т.п.
     Смотрите первый пример 'Hello, world!', там используется int 21h -
    прерывание номер 21h, которое отвечает за функции ДОС. В ah у нас было
    09h - это функция вывода текста на экран, начиная с адреса ds:dx.
    ---------------------------------------------------------------------------
    Q8: Что такое вектор прерывания?
    A: Это адрес, по которому будет сделан переход в случае вызова
    соотвествующего прерывания. Например, в случае, если в программе стоит
    'INT 21h', адрес перехода берется из ячейки по адресу 0000:21h*4 (по 4
    байта на один вектор прерывания).
    
    ----------------------------------------------------------------------------
    Q9: А как можно сгенерировать звук?
    A: Вот так:
    
     ;
     ; подпрограмма генерации звука
     ; Вход: АX= частота звука в Гц
     ;
     Sound proc near
     push ax ;сохранить регистры
     push bx
     push dx
     mov bx,ax ;частота
     mov ax,34DDh
     mov dx,12h ;(dx,ax)=1193181
     cmp dx,bx ;если bx < 18Гц, то выход
     jnb Done ;чтобы избежать переполнения
     div bx ;ax=(dx,ax)/bx
     mov bx,ax ;счетчик таймера
     in al,61h ;порт РВ
     or al,3 ;установить биты 0-1
     out 61h,al
     mov al,00001011b ;управляющее слово таймера:
     ;канал 2, режим 3, двоичное слово
     mov dx,43h
     out dx,al ;вывод в регистр режима
     dec dx
     mov al,bl
     out dx,al ;младший байт счетчика
     mov al,bh
     out dx,al ;старший байт счетчика
     Done:
     pop dx ;восстановить регистры
     pop bx
     pop ax
     ret
     Sound endp
    
    Выключение звука:
    
     No_Sound proc near
     push ax
     in al,61h ;порт РВ
     and al,not 3 ;сброс битов 0-1
     out 61h,al
     pop ax
     ret
     No_Sound endp
    
    ----------------------------------------------------------------------------
    Q10: Что лучше - стандартные или упрощенные директивы определения сегментов?
    A: Однозначно проще - упрощенные. Что лучше - решается индивидуально.
     Использование стандартных директив имеет смысл или в педагогических
     целях, или при наличии причин, требующих использования именно стандартных
     директив. Например, необходимость использования специальных имен
     сегментов, специальных атрибутов и особой группировки. Последнее
     опять-таки вовсе не означает, что упрощенные директивы не могут быть
     использованы. Например:
    
     .MODEL LARGE
     MyGroup group MySpecialSeg,$LibTable
     MySpecialSeg segment word public use16 'DATA'
     ...
     ends
     $LibTable segment para common use16 'DATA'
     ...
     ends
     .DATA
     .CODE
     end
    
     Поэтому вполне разумным видится использование упрощенных директив,
     совмещенное (при необходимости) с использованием стандартных.
    
    
    ---------------------------------------------------------------------------
    Q11: Для чего нужна команда LEA. То же самое может и OFFSET, да и Tasm заменяет
     LEA на MOV...OFFSET.
    A: MOV...OFFSET короче LEA, поэтому в режиме SMART tasm заменяет LEA на MOV
     для тех случаев, когда это возможно:
    
     lea di,Array
     mov di,offset Array
    
     Но такая замена возможна не всегда:
    
     lea di,Array[si+bx.FieldName]
    
     Логика работы LEA в данном случае эквивалентна такому фрагменту:
    
     mov di,offset Array
     add di,si
     add di,bx
     add di,FieldName
    
     Результат этого фрагмента не может быть вычислен на этапе компиляции
     из-за неизвестных величин, а следовательно, LEA в данном случае не может
     быть заменена командой MOV...OFFSET
    
    
    ---------------------------------------------------------------------------
    Q12: mov ax,@data
     mov ds,ax
    
     Откуда программа узнает адрес сегмента? После компиляции стоит mov ax,1.
     А в отладчике появляется сразу нужный адрес: mov ax,140Fh
     Кто его туда прописывает?
    
    A: Т.к. EXE может быть загружен по различным адресам, вместо явных значений
     cегментов в EXE указаны номера 16-байтных параграфов [0...FFFF] этих
     cегментов, начиная от начала образа EXE. Загрузчик, после считывания образа
     EXE в память, используя информацию в заголовке EXE, находит ссылки на
     явные значения сегментов и прибавляет к значению параграфа, указанное
     непосредственно в команде, реальное значение сегмента, начиная с которого
     загружен EXE.
    
     Например, образ EXE считан в память, начиная с адреса 140Eh:0 После
     корректировки значений сегментов вместо mov ax,1 получается mov ax,140F
    
    ---------------------------------------------------------------------------
    Q13: Как сделать COM с отладочной информацией, понимаемой TD ?
    A: comdbg.bat TEST
    
     tasm /zi %1
     tlink /v %1,%1,,,
     tdstrip -s -c %1.exe
    
    ----------------------------------------------------------------------------
    Q14: Не получается! COM есть, TDS есть, а TD отладочную информацию не видит:
     "Program has no symbol table"
    A: У TDS время меньше, чем у COM - такое бывает в Винде.
     Воспользуйтесь утилитой touch из NWDOS (в MS DOS она похуже)
    
     touch %1.tds
    
    ---------------------------------------------------------------------------
    Q15: Как расчитать количество памяти, необходимое для резидента?
    A: FirstFreeByteSeg - PspSeg + ((FirstFreeByteOffs+15) div 16)
    
    Resident macro FirstFreeByteSeg,FirstFreeByteOffs
     mov dx,FirstFreeByteSeg
     sub dx,[PspSeg]
     mov ax,FirstFreeByteOffs
     dec ax
     shr ax,4
     inc ax
     add dx,ax
    
     mov ah,31h
     mov al,[ErrorLevel]
     int 21h
    endm
    
    Resident seg Install,<offset Install>
    
    ---------------------------------------------------------------------------
    Q16: Не могу запустить дочернюю задачу функцией 4Bh
    Q17: Не выделяется память по функции 48h
    A: Нет свободной памяти.
    
    ---------------------------------------------------------------------------
    Q18: Да вроде все есть, почему не выделяет-то?
    A: Да потому что она уже тебе выделена, теперь ее осталось только сжать.
    
    ---------------------------------------------------------------------------
    Q19: Как сжать блок памяти, занимаемый программой?
    A: Сжимать ее следует через функцию DOS 4Ah. Алгоритм тот же, что и у
    макроса Resident:
    
    ShrinkMem macro FreeSeg,FreeOffs
     mov bx,FreeSeg
     sub bx,[PspSeg]
     mov ax,FreeOffs
    
     dec ax
     shr ax,4
     inc ax
    
     add bx,ax
     mov ah,4Ah
     mov es,[PspSeg]
     int 21h
    endm
    
    ShrinkMem <seg stack>,<(size stack)+1>
    В случае полного/дополнительного ручного объявления сегментов и их особого
    упорядочивания необходимо указать имя последнего сегмента.
    
    ----------------------------------------------------------------------------
    Q20: А что за команда такая rdtsc?
    A: read tsc - Read Time Stamp Counter. Читает регистр tsc, проще говоря
    возвращает в edx:eax количество тактов с момента последнего сброса
    процессора. Опкод - 0F 31, команда появилась на процессорах Pentium (и
    то не на всех.)
    
    ---------------------------------------------------------------------------
    Q21:. И еще, расскажите русским языком, что такое рекурсия (никогда не
     сталкивался!)?
    A: Вызов функцией самой себя.
    
    Q: Примерчик приветствуется.
    A: Классический пример - вычисление факториала:
    
    ..model farstack small, pascal
     .386
     locals @@
    ..stack 2048
    ..code
    Factorial PROC ; function factorial(@@N:Word):DWord;
     arg @@N:word ; begin
     mov ax,@@N
     cmp ax,1 ; if (@@N=1) or (@@N=0) then
     ja @@calc
     mov ax,1 ; factorial:=1
     xor dx,dx
     ret
    @@calc:
     dec ax ; else
     push ax
     call Factorial ; factorial := factorial(@@N-1)
     mul @@N ; * @@N;
     ret ; end;
    endp
    
    MAIN PROC
     .startup
     push 4
     call Factorial
     .exit
    ENDP
    
    end MAIN
    
    
    ----------------------------------------------------------------------------
    Q22: Расскажите про сопроцессор, как его использовать?
    A: Вот тебе пример программы с комментариями:
    
    ..model tiny
    ..code
    ..386 ; привычка :)
    ..387 ; использование сопроца
    ..startup
    
     finit ; инициализация сопроца
     fild data1 ; загрузка data1
     fiadd data2 ; складывание с data2
     fist _result ; сохранение результата в
     ; _result
    
     ret
    data1 dw 1
    data2 dw 200
    _result dw ?
    
    end
    
    Теперь немного теории.
    Пример команды:
    fild
    ^^^^
    ||++
    |||
    ||+-- 'ld' - load, загрузка числа в стек сопроцессора
    |+--- 'i' - integer, означает, что работаем с ЦЕЛЫМИ данными (
    | еще варианты - '', то есть fld, например - загрузка вещественного
    | числа в сопроцессор, 'b', т.е. fbld - загрузка BCD числа)
    +---- 'f' - обозначает, что это команда сопроцессора
    
    Примеры команд:
    
    fld data1 ; загрузка вещественного числа из памяти
     ; по адресу data1 в сопроцессор
    
    fist _result ; сохранение числа как целого в память по
     ; адресу _result (при необходимости оно
    округляется -
     ; это делает сам сопроц)
    
    fistp _result ; то же самое, но при сохранении числа оно
     ; выталкивается из стека сопроца
    
    fsqrt ; вычисление квадратного корня из st0, то
     ; есть аргумент берется из стека, туда же и
     ; помещается значение корня
    
    fcos, fsin ; вычисляет косинус и синус угла, заданного
     ; в стеке сопроца. Угол должен быть в
     ; _радианах_.
    
    fsincos ; одновременно вычисляет и sin и cos, в
     ; st0 помещается sin, в st1 - cos.
    
    
    Вообще для понимания механизма работы возьмите Turbo Debugger:
    
    F10/View/Numeric processor:
    Здесь видно, что в стеке сопроца находится число 300 :)
    
    +=[x]=80486 IPTR=54CE3 OPCODE=706 OPTR=54CEE==2=[][]=+
    |Valid ST(0) 300 | im=1 | ie=0 |
    |Empty ST(1) | dm=1 | de=0 |
    |Empty ST(2) | zm=1 | ze=0 |
    |Empty ST(3) | om=1 | oe=0 |
    |Empty ST(4) | um=1 | ue=0 |
    |Empty ST(5) | pm=1 | pe=0 |
    |Empty ST(6) |iem=0 | ir=0 |
    |Empty ST(7) | pc=3 | cc=0 |
    | | rc=0 | st=7 |
    | | ic=0 | |
    +xXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX+======+=====-+
    
    Выполняем:
    
    cs:0107 D9FA fsqrt
    
    +=[x]=80486 IPTR=54CE7 OPCODE=1FA OPTR=54BE0==2=[][]=+
    |Valid ST(0) 17.320508075688773 | im=1 | ie=0 |
    |Empty ST(1) | dm=1 | de=0 |
    |Empty ST(2) | zm=1 | ze=0 |
    |Empty ST(3) | om=1 | oe=0 |
    |Empty ST(4) | um=1 | ue=0 |
    |Empty ST(5) | pm=1 | pe=1 |
    |Empty ST(6) |iem=0 | ir=0 |
    |Empty ST(7) | pc=3 | cc=0 |
    | | rc=0 | st=7 |
    | | ic=0 | |
    +xXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX+======+=====-+
    
    Получили вещественное число в стеке сопроцессора. Сохраним его в памяти
    по адресу ds:[110] как целое:
    
    cs:0109 DF1E1001 fistp word ptr[0110]
    
    Смотрим содержимое:
    
    ds:0110 11 00 FF 16 57 9A A5 1B
     ^^^^^ вон он наш результат :)
    
    ----------------------------------------------------------------------------
    Q23: Народ, как обойти "Relative jump out of range"?
    A: Поставь директиву .386 или даже больше - .586, напpимеp - и
    наслаждайся... ;) А по умолчанию используется 8086. У него только jmp
    short есть.
    A2: А если все же пpиспичило писать под пpоцессоp менее 386, то можно
    воспользоваться директивой 'jumps':
    
    JUMPS
     ....
     CMP чего надо
     JZ куда надо
     ....
    NOJUMPS
    
    И это автоматом постpоит констpукцию, подобную этой:
    
     CMP чего надо
     JNZ @2
     JMP куда_надо
    @2:
    
     Диpектива JUMPS заменяет все коpоткие пеpеходы на такую
    констpукцию, в случае необходимости. Поэтому пользоваться ей можно
    всегда.
    
    ----------------------------------------------------------------------------
    Q25: А что такое CMOS и как с ней работать?
    A: Сейчас под термином CMOS (в рамках компьютерщиков) понимают 64 (уже
    говорят, что 128) байт энергонезависимой памяти.
     PC класса AT имеют питаемые от батарейки часы реального времени
    (RTC) и 64 байта постоянной CMOS-памяти.
     Эта память содержит разнообразную информацию, включающую текущие
    дату и время, сведения о конфигурации машины и байт статуса закрытия
    системы (этот байт используется механизмом, позволяющим машине AT
    рестартовать после выполнения сброса процессора, выводящего из
    защищенного режима).
    
    Работать с ней надо так:
    
     Чтобы прочитать байт из CMOS, выполните команду OUT 70H, адрес;
    затем выполните IN 71H. Чтобы записать байт в CMOS, выполните OUT 70H,
    адрес; затем OUT 71H, значение.
    
    Пример: ;------- прочитать тип установленного твердого диска
     mov al,12H
     out 70H,al ;выбрать адрес CMOS 12H
     jmp $+2 ;требуется небольшая задержка
     in al,71H ;теперь в AL тип устройства (0-15)
    
     Адреса 10H..20H защищены контрольной суммой, что позволяет
    обнаружить износ батарейки или порчу информации в записи конфигурации.
    Контрольная сумма - это просто 16-битовая сумма защищаемых байт памяти.
    ----------------------------------------------------------------------------
    Q26: Тут такое дело, в процедурах у меня часто метки одинаковые, или
    вставляю из разных своих исходников куски, tasm ругается, мол, метки
    одинаковые :( Приходится все иправлять... Что сделать-то можно? И вообще
    как можно удобно сделать работу с метками?
    A: Есть два способа, один простой, другой хитрый :)
    
    Способ простой: ставим в начале исходника locals @@ и все метки,
    начинающиеся с символов '@@' будут _локальными_, то есть существовать в
    пределах одной процедуры и не вызывать конфликта с одинаковыми именами.
    
    Способ хитрый: у tasm'а есть такой режим работы, при котором существуют
    метки типа @@,@b,@f (@b и @f соответственно переходят на ближнюю метку
    @@ назад, либо вперед), этот режим включается словами 'masm' и 'quirks'
    (обязательны обе директивы, иначе работать не будет!). Работает так:
     +------------+
    @@:| |
     + nop |
     nop |
     jmp @b -+
     nop
     jmp @f -+
    @@:+ nop |
     +------------+
    ----------------------------------------------------------------------------
    Q27: А как напечатать число в шестнадцатеричном виде?
    A: Можно сделать так:
    (результат помещяется в es:di)
    
    byte2hex proc near
     push cx
     mov cx,2
    @@L1: rol dl,4
     mov ax,300fh
     and al,dl
     aaa
     aad 11h
     stosb
     loop @@L1
     pop cx
     ret
    byte2hex endp
    
    word2hex proc near
     push cx
     mov cx,2
    @@L1: rol dx,8
     call byte2hex
     loop @@L1
     pop cx
     ret
    word2hex endp
    
    dword2hex proc near
     mov cx,2
    @@L1: rol edx,16
     call word2hex
     loop @@L1
     ret
    dword2hex endp
    
    >Еще:
    Преобразует hex-цифру в AL в ASCII-код
    
    Вход: AL - hex-цифра (00h - 0Fh)
    Выход: AL - ASCII - код символа.
    
    cmp al,10
    sbb al,69h
    das
    
    Вот и всё!
    
    После SBB числа 0-9 превращаются в 96h - 9Fh, а числа 0Ah - 0Fh - в 0A1h -
    0A6H. Затем DAS вычитает 66h из первой группы чисел, переводя их в 30h - 39h, и
    60h из второй группы чисел, переводя их в 41h - 46h
    
    >А вот наиболее очевидный но немного менее быстрый и удобный способ: команда
    XLATB. Она помещает в AL байт из таблицы в памяти по адресу ES:BX (или ES:EBX)
    со смещением относительно начала таблицы равным AL.
    
    Пример:
    
    Вход: AL - hex-цифра (00h - 0Fh)
     ES - сегментный адрес таблицы.
    
    Выход: AL - ascii-код символа.
    
    В сегменте кода:
    
    lea bx,htable
    xlatb
    
    В сегменте данных:
    
    htable db "0123456789ABCDEF"
    
    Вот и все.
    
    
    ----------------------------------------------------------------------------
    Q28: А как слинковать драйвер устройства (sys, или просто сделать файл с
    org0?)
    A: Вот так:
    tasm driver.asm /m4
    tlink driver.obj, driver.sys /t
    > ^ обратите внимание, это самое главное :)
    
    p.s. Есть одна тонкость, на которую я напоролся и имел много проблем.
    Тонкость вот в чем. Если у вас tlink вызывается через батник, то
    слинковать драйвер вы не сможете, так как батник при разборе параметров
    %1 %2 и т.п. НЕ передаст tlink'у символ запятой, которая здесь играет
    решающую роль. Так что линкуйте без батника, либо в нем явно напишите
    'tlink driver.obj, driver.bin /t'
    ----------------------------------------------------------------------------
    
    Q29: Программа выполняется под Turbo Debugger'ом.
     А если её запустить без него, то она виснет/работает неправильно.
    Q29: Программа выполняется в операционной системе X.
     А в операционной системе Y - виснет.
    
    A: Возможная причина - программа предполагает, что регистр AA имеет значение
     BB при старте, а инициализация регистров в различных ОС и отладчиках может
     отличаться. Регистры нужно инициализировать самому, не полагаясь на то,
     что при старте в них должно быть что-то записано. Исключение из этого
     правила - сегментные регистры.
    ----------------------------------------------------------------------------
    
    Q30: А как под Windows на ассемблере писать?
    A: Чтобы писать на ассемблере под Windows. нужен MASM 5 for Windows
    (http://win32asm.newmail.ru/), либо TASM 5 с include-файлами.
    
    Пример программы на Tasm'е:
    
    (комментарии - Anatoly Romashkin)
    
    ;tasm32 /m /ml file.asm - если нет tasm32, то можно попpобовать tasm 4.1
    ;tlink32 /c file.obj
    
    ..386
    ..model flat, stdcall
    includelib import32.lib
    
    extrn MessageBoxA:proc
    extrn ExitProcess:proc
    
    o equ offset
    MB_OK equ 0
    
    ..data ; y меня tasm 4.1 мог глючить, если нет данных
    MsgCaption db 'Qwerty',0
    MsgText db 'Hello, World!',0
    
    ..code
    start: call MessageBoxA, 0, o MsgText, o MsgCaption, MB_OK
     call ExitProcess, 0
    end start
    
    Пример консольной программы:
    
    ;tasm32 /m /ml file.asm - если нет tasm32, то можно попpобовать tasm 4.1
    ;tlink32 /c /ap file.obj
    
    ..386
    ..model flat, stdcall
    includelib import32.lib
    
    extrn ExitProcess:proc
    extrn GetStdHandle:proc
    extrn WriteFile:proc
    extrn ReadFile:proc
    extrn SetConsoleMode:proc
    
    o equ offset
    STD_INPUT_HANDLE equ -10
    STD_OUTPUT_HANDLE equ -11
    MB_OK equ 0
    
    ..data ; y меня tasm 4.1 мог глючить, если нет данных
    MsgText db 'Hello, World!'
    MsgTextLen=$-MsgText
    hIn dd 0
    bWritten dd 0
    Buff db 0
    BuffLen=$-Buff
    
    ..code
    start:
     call GetStdHandle, STD_OUTPUT_HANDLE
    ;полyчаю стандаpтный хэндл в eax
     call WriteFile, eax, o MsgText, MsgTextLen, o bWritten, 0
    ;пишy в stdout
     call GetStdHandle, STD_INPUT_HANDLE
     mov hIn, eax
     call SetConsoleMode, eax, 0
    ;yстанавливаю pежим консоли
    GetEnter: call ReadFile, hIn, o Buff, BuffLen, o bWritten, 0
    ;читаю с stdin
     cmp Buff, 0dh ;enter
     jne GetEnter
    
     call ExitProcess, 0
    
    end start
    
    Если не будет pаботать пеpвый ваpиант компиляций указанный в коментаpиях
    пpогpаммы или скомпилится с галами, то попpобуйте пpогpаммы откомпилиpовать
    вот так:
    tasm32 /ml !.asm
    tlink32 /Tpe /aa /c !.obj
    
    
    ----------------------------------------------------------------------------
    Qlast: А как это ... сделать?
    A: Напишите в эху, вам ответят :)
    
    ----------------------------------------------------------------------------
    Ссылки в интернете:
    
    Сайт Владислава Пирогова (примеры под Windows, куча книг!)
    http://asm.shadrinsk.net/
    
    Ассемблер NASM (freeware)
    http://nasm.2y.net
    
    Куча ссылок
    http://www.ee.mu.oz.au/pgrad/apsh/assembler.htm
    
    Дока по NASM на русском языке (спасибо AsmOS Team)
    http://asmdev.narod.ru/asmos/our_files/docs/nasm.win.rar
    
    Interrupt list (хорошее описание прерываний)
    http://www.pobox.com/~ralf
    
    Различные базы, дополнения, NG, TechHelp!.
    http://www.whitetown.com/ru/ng/
    http://www.shortway.to/posohov
    
    Программирование на ASM'е под Windows:
    http://win32asm.newmail.ru/
    
    TechHelp! 4.0 RUS
    http://zigar.narod.ru/techhelp.zip
    
    Хоpоший тyтоpиал asm под Win32
    http://www.wasm.zite.ru/win32asmtutor/files/tutorial/contents.html
    
    Asm под DOS, аpхив pассылки. Полезно, но написано кpиво, поэтомy читать
    сложно и неинтеpесно. Но полезно.
    http://www.kalashnikoff.ru/Assembler/Issues/index.htm
    
    
    Бypжyйский сайт, тоже есть тyтоpиалы и пpого пpимеpов. Win32.
    http://spiff.tripnet.se/~iczelion/
    
    Список пpеpываний. Понадобится навеpняка. (2.7 mb, на английском)
    http://www.cs.cmu.edu/~ralf/interrupt-list/inter61a.zip
    ....
    http://www.cs.cmu.edu/~ralf/interrupt-list/inter61f.zip
    
    
    Не знаю что там, пpосто URL'ы валялись.
    http://win32asm.chat.ru/
    http://www.thomasbleeker.nl/exagone/page/int.html
    http://sources.fitkursk.ru/articles/art0000037.asp
    
    
    ----------------------------------------------------------------------------
    FAQServer 2:5058/96.111
    ----------------------------------------------------------------------------
    
    Все вопросы по содержанию и дополнению FAQ'а отправлять мне -
    Alexander Zigar' 2:5058/96
    
    В создании FAQ принимали участие:
    
     Alexander Zigar' 2:5058/96
     Anatoly Romashkin 2:5093/56
     Dima Marakasov 2:5020/1826.5
     Kirill Barashkin 2:5080/500.271
     Max Vorobyov 2:5025/150.24
     Mihail Epihin 2:5023/29.34
     Roman Perminov 2:5070/313
     Semen Panevin 2:5025/121.8
     Victor Petrenko (AsmOS Team) 2:5061/6.40
     Yury Suharev 2:5023/19.11
     И все те, кого я забыл упомянуть...
    
     Также спасибо всем подписчикам эх RU.ASM.CHAINIK, TALKS.ASM, PC.CODING и
     им подобных.
    Просмотров: 2516 | Добавил: Turbokherson | Рейтинг: 0.0/0
    Всего комментариев: 0
    Имя *:
    Email *:
    Код *:
    Создать бесплатный сайт с uCozCopyright MyCorp © 2024