Трансляция ассемблерной программы

Мы написали ассемблерную программу, которую назвали, например, temp.asm. Теперь эту программу нужно оттранслировать с помощью tasm.exeи получить из нее файл temp.obj. Затем, с помощью программы tlink.exe, файл temp.objпреобразуется в исполняемый файл temp.exe (или temp.com).

Для того, чтобы получить файл temp.objнадо набрать в командной строке:

tasm.exe temp. asm(можно и проще: tasm temp)

и нажать ENTER. Конечно при этом tasm.exeи temp.asmдолжны быть, допустим, в той директории, где мы сейчас работаем (доступны компьютеру). Транслятор может и не создать файл temp.obj, если он найдет в программе ошибки.

Далее надо получить исполняемый файл. Для создания EXE программы надо набрать в командной строке:

tlink.exe temp.obj(или tlink temp)

а для COM программы:

tlink.exe temp.obj /t(или tlink temp /t).

Вообще, очень удобно создать bat– файл, поскольку при отладке программу постоянно приходится транслировать заново. Работа tlink.exeтакже не всегда завершается созданием исполняемого файла. Это бывает, если tlink.exeнашел в программе ошибки.

Приведем пример трансляции.

code segment; (строка 1)

assume cs:code, ds:code; (строка 2)

; пропущена директива org 100h

start:; (строка 4)

jmp begin; (строка 5)

mad db 100, 99, 98,; (строка 7) лишняя запятая после 98

db 97, 96; (строка 8)

nic dw 380; (строка 10)

begin; (строка 12) пропущено двоеточие после begin

mov ah. 7 ; (строка 14) вместо точки нужна запятая

mov al, nic; (строка 15) не согласована разрядность регистра и операнда

int21h; (строка 16) пропущен пробел

mov si, offset madd; (строка 17) неправильно написано имя массива

mov [si+3], 5; (строка 18) не определен формат записываемой информации

Mov ah, 4ch

Int 21h

Code ends

End start

Мы написали эту программу (для COM формата) и назвали ее temp.asm. Эта программа не имеет никакого смысла, так как не выполняет никакой полезной и даже здравой работы. Зато в программе намеренно сделаны ошибки, каждая из которых описана в той же строке, где она находится.

Теперь мы создали файл temp.bat:

Tasm temp

Tlink temp /t

и запустили его. Вот что мы получим:

Assembling file: temp.ASM

**Error** temp.ASM(5) Undefined symbol: BEGIN

*Warning* temp.ASM(7) Missing operand - trailing ? assumed

**Error** temp.ASM(12) Illegal instruction

**Error** temp.ASM(14) Too few operands to instruction

**Error** temp.ASM(15) Operand types do not match

**Error** temp.ASM(16) Illegal instruction

**Error** temp.ASM(17) Undefined symbol: MADD

*Warning* temp.ASM(18) Argument needs type override

Error messages: 6

Warning messages: 2

Passes: 1

Remaining memory: 381k

D:\MY_DIR\ASSEMBL>d:\my_dir\assembl\tlink temp /t

Turbo Link Version 7.00 Copyright (c) 1987, 1994 Borland International

Fatal: Unable to open file 'temp.obj'

Обратите внимание, что транслятор для каждой ошибки написал в скобках номер строки, в которой он эту ошибку нашел. Так что обычно ошибка легко находится программистом. ERROR– это ошибки, их надо исправлять, WARNING –предупреждения, довольно часто (но не всегда!) их можно игнорировать. Объектный файл из-за ошибок создан не был, поэтому tlinkвыдал сообщения о фатальной ошибке.

Исправим в нашей программе все ошибки, кроме одной:

code segment; (строка 1)

assume cs:code, ds:code; (строка 2)

; пропущена директива org 100h

start:; (строка 4)

jmp begin; (строка 5)

mad db 100, 99, 98; (строка 7)

db 97, 96; (строка 8)

nic dw 380; (строка 10)

begin:; (строка 12)

mov ah, 7 ; (строка 14)

mov al, byte ptr nic ; (строка 15)

int 21h; (строка 16)

mov si, offset mad ; (строка 17)

mov byte ptr [si+3], 5 ; (строка 18)

Mov ah, 4ch

Int 21h

Code ends

End start

и вновь запустим наш bat файл. Теперь мы получим:

Assembling file: temp.ASM

Error messages: None

Warning messages: None

Passes: 1

Remaining memory: 381k

D:\MY_DIR\ASSEMBL>d:\my_dir\assembl\tlink temp /t

Turbo Link Version 7.00 Copyright (c) 1987, 1994 Borland International

Fatal: Cannot generate COM file : invalid initial entry point address

Теперь tasm«доволен всем» и объектный файл создан, а вот tlinkотказывается генерировать СОМ файл. Если мы теперь исправим оставшуюся ошибку (вставим org 100h), то после трансляции будем иметь сообщение:

Assembling file: temp.ASM

Error messages: None

Warning messages: None

Passes: 1

Remaining memory: 381k

D:\MY_DIR\ASSEMBL>d:\my_dir\assembl\tlink temp /t

Turbo Link Version 7.00 Copyright (c) 1987, 1994 Borland International

а наш СОМ файл будет создан.

ПРИМЕРЫ ПРОГРАММИРОВАНИЯ НА АССЕМБЛЕРЕ.

Наша первая программа.

В качестве первого примера программы на любом языке обычно используется программа, выводящая на экран надпись: HELLO, WORLD! Давайте и мы напишем такую же программу, но, что бы было интересней, несколько ее усложним.

Итак, вот что будет делать наша программа:

ü Очищать экран (белым цветом);

ü Устанавливать курсор, так чтобы надпись выводилась в центр экрана;

ü Выводить надпись в позицию курсора (черным цветом);

ü Ждать нажатия клавиши. Если нажата одна из клавиш b (blue), g(green) или r(red), цвет надписи меняется соответственно на синий, зеленый или красный. Если нажата клавиша ESC, программа завершает свою работу.

Приведем вначале текст программы:

; программа написана в СОМ формате

Code segment

Assume cs:code, ds:code

Org 100h

start:

Jmp begin

message db 'HELLO, WORLD!'; надпись, которую мы будем выводить

attributes db 70h; исходные атрибуты экрана и надписи
; экран – белый, надпись - черная

curs_x db 35 ; координата Х курсора (№ столбца)

curs_y db 12; координата Y курсора (№ строки)

begin:

; чистим экран

mov ch, 0; координата Y левого верхнего угла экрана (№ строки)

mov cl, 0; координата Х левого верхнего угла экрана (№ столбца)

mov dh, 24; координата Y правого нижнего угла экрана(№ строки)

mov dl, 79; координата Х правого нижнего угла экрана (№ столбца)

mov al, 0; чистить всю заданную область(то есть, у нас, весь экран)

mov bh, 70h; атрибуты (черный символ на белом фоне)

mov ah, 6; функция

Int 10h

m4:

; выводим надпись

mov di, 13; всего выводим 13 символов

mov si, offset message; в siадрес первой буквы надписи

m1:

; позиционируем курсор

mov dh, curs_y; в dhстрока

mov dl, curs_x; в dl столбец

mov bh, 0; в bh№ видеостраницы (для нас начинающих всегда 0)

mov ah, 2; функция

Int 10h

; собственно вывод надписи. Курсор при таком выводе (для нас, УВЫ!) не сдвигается

mov ah, 9; функция

mov bl, attributes; атрибуты

mov cx, 1; коэффициент повторения (сколько раз выводить символ)

mov al, [si]; в al выводимый (на экран в позицию курсора) символ

Int 10h

inc si; в siадрес следующей буквы надписи

inc curs_x; сдвигаем координату Х на одну позицию вправо

dec di; уменьшаем diна единицу

jnz m1; если в di «не ноль», идем на переустановку курсора
; и вывод следующей буквы надписи

mov curs_x, 35; восстанавливаем исходную координату курсора по Х

mov ah, 0; функция

int 16h; здесь висим и ждем нажатия клавиши. Когда клавиша
; нажата ее скэн-код вернется в ah, а ASCII-код – в al.

cmp al, 1bh; это ESC? (1bh - ASCII-код клавиши ESC)

je exit; если «да», идем на выход. «Нет» - проверяем дальше

cmp al, 'r'; это r?

jne m2; «нет» - проверяем дальше

mov attributes, 74h; «да» - меняем атрибуты

jmp m4; и идем на вывод надписи сначала. Старую надпись мы
; не стираем, просто пишем поверх нее новую надпись
; с другими атрибутами

m2:

cmp al, 'g'; далее аналогично

Jne m3

Mov attributes, 72h

Jmp m4

m3:

cmp al, 'b'

jne m4; это вообще «не наша» клавиша, мы ее проигнорируем

Mov attributes, 71h

Jmp m4

; выход из программы. Мы сюда попадем, только если нажмем ESC

exit:

Mov ah, 4ch

Int 21h

Code ends

End start

Не надо думать, что это оптимальная программа. Давайте, для примера, напишем другой вариант этой программы, теперь в EXE формате.

Stack segment stack

Db 100 dup (0)

Stack ends

Data segment

message db 'HELLO, WORLD!$'; надпись, которую мы будем выводить

attributes db 70h; исходные атрибуты экрана и надписи
data ends

Code segment

Assume cs:code, ds:data

start:

Mov ax, data

Mov ds, ax

; чистим экран

m4:

mov ch, 0; координата Y левого верхнего угла экрана (№ строки)

mov cl, 0; координата Х левого верхнего угла экрана (№ столбца)

mov dh, 24; координата Y правого нижнего угла экрана(№ строки)

mov dl, 79; координата Х правого нижнего угла экрана (№ столбца)

mov al, 0; чистить всю заданную область(то есть, у нас, весь экран)

mov bh, attributes; текущие атрибуты

mov ah, 6; функция

Int 10h

;позиционируем курсор

mov dh, 12; в dhстрока

mov dl, 35; в dl столбец

mov bh, 0; в bh№ видеостраницы (для нас начинающих всегда 0)

mov ah, 2; функция

Int 10h

; выводим надпись

mov ah, 9; функция

mov dx, offset message; в dxадрес первой буквы надписи

int 21h; выводим все до доллара

mov ah, 0; функция

int 16h; здесь висим и ждем нажатия клавиши. Когда клавиша
; нажата ее скэн-код вернется в ah, а ASCII-код – в al.

cmp al, 1bh; это ESC? (1bh - ASCII-код клавиши ESC)

je exit; если «да», идем на выход. «Нет» - проверяем дальше

cmp al, 'r'; это r?

jne m2; «нет» - проверяем дальше

mov attributes, 74h; «да» - меняем атрибуты

jmp m4; и идем на новую очистку экрана, установку курсора
; и вывод надписи

m2:

cmp al, 'g'; далее аналогично

Jne m3

Mov attributes, 72h

Jmp m4

m3:

cmp al, 'b'

jne m4; это вообще «не наша» клавиша, мы ее проигнорируем

Mov attributes, 71h

Jmp m4

; выход из программы. Мы сюда попадем, только если нажмем ESC

exit:

Mov ah, 4ch

Int 21h

Code ends

End start

Программа получилась несколько проще. При каждом нажатии любой клавиши (кроме ESC) мы заново очищаем экран с текущими атрибутами, а потом выводим на него надпись, начиная с позиции курсора, который мы все время устанавливаем в одно и тоже место. Недостаток этой программы заключается в постоянной очистке экрана. На медленных компьютерах человеку будет видно мерцание экрана.

Наши рекомендации