
СПО / Полезная информация для программирования на Ассемблере
.docНаиболее частые ошибки компиляции
-------------------------------------------------------------------------------------------------------------
Ошибочная запись:
mov bx, FFh
**Error** Undefined symbol: FFH (Неопределённый символ FFH)
Правильная запись:
mov bx, 0FFh
Вывод:
Если шестнадцатеричное число начинается с буквы, то перед ней надо ставить 0
-------------------------------------------------------------------------------------------------------------
Некорректная запись:
mov [bx],0FFh
*Warning* Argument needs type override (Требуется явно указать тип операнда)
Пояснения: Требуется явно указать размер, или тип, выражения, т.к. он не может быть определен из контекста
Правильная запись:
mov byte ptr [bx],0FFh
или
mov word ptr [bx],0FFh
Примечания: кроме выражений
byte ptr (байт = 1 байт = 8 бит)
и
word ptr (слово = 2 байта = 16 бит)
можно ещё использовать выражения
dword ptr (двойное слово = 4 байта = 32 бита)
и
qword ptr (учетверённое слово = 8 байт = 64 бита)
tbyte ptr (десять байт = 10 байт = 80 бит)
но размеры последующих аргументов должны быть соответствующими
-------------------------------------------------------------------------------------------------------------
Ошибочная запись:
mov ebx, 0FFh
**Error** Undefined symbol: EBX (Неопределённый символ EBX)
Пояснения: 32-битные регистры поддерживаются начиная только с процессоров i386, поэтому в начале программы надо указать Ассемблеру, что мы пишем программу для соответствующего процессора (по умолчанию подразумевается процессор i8086):
Правильная запись:
.386
…
mov ebx, 0FFh
Примечания: Директивы задания набора допустимых команд
.8086 – используется по умолчанию. Разрешены только команды 8086;
.186 – разрешены команды 80186;
.286 и .286c – разрешены непривилегированные команды 80286;
.286p – разрешены все команды 80286;
.386 и .386c – разрешены непривилегированные команды 80386;
.386p – разрешены все команды 80386;
.486 и .486c – разрешены непривилегированные команды 80486;
.486p – разрешены все команды 80486;
.586 и .586c – разрешены непривилегированные команды P5 (Pentium);
с – разрешены все команды P5 (Pentium);
.686 – разрешены непривилегированные команды P6 (Pentium Pro, Pentium II);
.686p – разрешены все команды P6 (Pentium Pro, Pentium II);
.8087 – разрешены команды NPX 8087;
.287 – разрешены команды NPX 80287;
.387 – разрешены команды NPX 80387;
.487 – разрешены команды FPU 80486;
.587 – разрешены команды FPU 80586;
.MMX – разрешены команды IA MMX;
.K3D – разрешены команды AMD 3D.
-------------------------------------------------------------------------------------------------------------
Ошибочная запись:
mov word ptr [ax], 0FFh
**Error** Illegal indexing mode (Недопустимы режим индексации)
Пояснения: не все 16-разрядные регистры можно использовать для косвенной индексации:
нельзя использовать: ax, cx, dx, sp
можно использовать: bx, bp, si, di
Правильная запись:
mov word ptr [bx], 0FFh
-------------------------------------------------------------------------------------------------------------
Ошибочная запись:
push al
pop bh
**Error** Argument to operation or instruction has illegal size (Аргумент для операции или инструкции имеет недопустимый размер)
Правильная запись:
push ax
pop bx
Примечания: команды PUSH и POP не могут работать в 1-байтными операндами. Размер операнда должен быть не меньше 2 байт
Конструкция если … то … иначе |
Вариант 1 (с проверкой соответствующих условий) |
Вариант 2 (с проверкой противоположных условий) |
… если AX = BX то действие1 иначе если AX > BX то действие2 иначе действие3 конец … |
… cmp AX,BX je Label_1 jg Label_2 действие3 jmp end_L Label_1: действие1 jmp end_L Label_2: действие2 end_L: … |
… cmp AX,BX jne Label_2 действие1 jmp end_L Label_2: jl Label_3 действие2 jmp end_L Label_3: действие3 end_L: … |
Конструкция выбор из … |
Вариант 1 (с проверкой на равенство соответствующим значениям) |
Вариант 2 (с проверкой на неравенство соответствующим значениям) |
… выбор AX из значение1: действие1 значение2: действие2 . . . . . значениеN: действиеN иначе действие0 конец … |
… cmp AX, значение1 je Label_1 cmp AX, значение2 je Label_2 . . . . . cmp AX, значениеN je Label_N действие0 jmp end_L Label_1: действие1 jmp end_L Label_2: действие2 jmp end_L . . . . . Label_N: действиеN jmp end_L действие0 end_L: … |
… cmp AX, значение1 jne Label_2 действие1 jmp end_L Label_2: cmp AX, значение2 jne Label_3 действие2 jmp end_L Label_3: cmp AX, значение3 . . . . . Label_N: cmp AX, значениеN jne Label_0 действиеN jmp end_L Label_0: действие0 end_L: … |
Конструкция цикл (Случай простого выполнения цикла N раз) |
Вариант 1 (с использованием команды LOOP) [CX изменяется от N до 1] |
Вариант 2 (без использования команды LOOP) [CX изменяется от 1 до N] {Вместо СХ можно использовать другой регистр} |
… цикл для CX от 1 до N действие конец … |
… push CX (mov AX,CX) mov CX, N loop_L: действие loop loop_L pop CX (mov CX,AX) … |
… push CX (mov AX,CX) mov CX, 1 loop_L: действие inc CX cmp CX, N jbe loop_L pop CX (mov CX,AX) … |
Конструкция цикл (Общий случай изменения значений переменной цикла) |
Случай 1 [Изменение значений переменной цикла от N1 до N2] |
Случай 1 [Изменение значений переменной цикла от N2 до N1] |
… цикл для AX от N1 до N2 действие конец … |
… mov AX, N1 loop_L: действие inc AX cmp AX,N2 jle loop_L … |
… mov AX, N2 loop_L: действие dec AX cmp AX,N1 jge loop_L … |