MOV #5, - M+2*3(R5)
; m[i] = 7
MOV I, R0
ASL R0
ADD R5, R0
MOV #7, - M(R0)
Дома: для I8086
Двумерные массивы
адрес m[i][j]= m+((i*число столбцов)+j)*размер_элем
Статический short m[20][30]:
; PDP-11
M: .BLKW 20.*30.
I: . WORD 0
J: . WORD 0
I8086 - дома
; m[2][4] = 7
; PDP-11
MOV #7, M+((2*30)+4)*2
I8086 - дома
; m[i][4] = 6
; PDP-11
MOV I, R0
MUL #60., R0 ; I*30*2
MOV #6, M+8.(R0)
I8086 - дома
; m[2][j] = 5
; PDP-11
MOV J, R0
ASL R0 ; J*2
MOV #5, M+30.*2*2(R0)
I8086 - дома
Дома: все эти примеры для случая локального массива m на двух ассемблерах
Структуры(записи)
struct STRU
{ char ch1; long l1,l2; short i1,i2;} s1,*ps = s1;
PDP-11:
S1: .BLKB 14.
PS: .WORD S1
Смещения к полям:
CH1 = 0
L1 = 2 ; адрес для long
; должен быть четным
L2 = 6
I1 = 10.
I2 = 12.
; s1.ch1 = ‘A’; ps->ch1 = ‘B’;
MOVB #’A, S1
MOVB #’B, @PS
; s1.i1 = 3; ps->i2 = 4;
MOV #3, S1+I1
MOV PS, R0
MOV #4, I2(R0)
; ps->l2 = 2
MOV PS, R0
MOV #2, L2(R0); младшую часть
; располагаем
; в первом слове
CLR L2+2(R0) ; старшую – во втором
Дома:
а) то же для I8086,
б) s1 и ps в стеке для двух ассемблеров
Списки
Однонаправленный:
![]() |
struct ELIST
{ struct ELIST *next; T_INFO info;}
*first, *scan;
Перемещение вперед:
scan = scan->next;
PDP-11:
MOV @SCAN, SCAN
I8086:
MOV SI, SCAN
MOV SCAN, [SI]
Для регистрового scan:
PDP-11: MOV (R2), R2
I8086: MOV SI, [SI]
Макрообработка в ассемблере
1. Общая идея
![]() |
2. Простейшие конструкции
Базовые директивы определения именуемых констант:
· Директива прямого присвоения
имя = числовое выражение
· Директива equ
имя equ строка или числовое выражение
Идентификаторы, определенные с помощью “=” можно переопределять, а определенные с помощью equ – нельзя.
Расширенные директивы определения именуемых строковых констант(TASM3..):
Слияние строк: имя catstr строка1, строка2, …
Выделение подстроки:
имя substr строка, нач_позиция, число_символов
Вхождение одной строки в другую:
имя instr [нач_позиция,]строка1, строка2
Определяет номер той позиции строки1, начиная с которой строка2 входит в нее в качестве с подстроки. Если задана нач_позиция, то поиск выполняется от нее, а не от позиции 1.
Определение длины строки:
имя sizestr строка
3. Макрокоманды
Макроопределение:
имя macro формальные параметры
строки макроопределения
endm
Макровызов: имя фактические_параметры
Пример:
push3 macro x1,x2,x3
push x1
push x2
push x3
endm
Пример вызова:
push3 si, [bx+di+4], cx
Фактический параметр в списке директивы вызова макрокоманды это
· либо строка без разделителей
· либо строка с разделителями внутри, но обрамленная угловыми скобками <..>
· либо строка, где разделители фильтруются символом “!”
Если требуется сгенерировать подстроку фактического параметра с текстом числового выражения, то это числовое(константное) выражение вставляется в текст фактического параметра с префиксом “%”
Формальный параметр может иметь кроме базовой части, еще и постфиксную
имя[:постфикс]
Если постфикс равен REQ, то фактический аргумент обязателен в строке вызова макрокоманды.
Если постфикс представляет собой конструкцию =<строка_по_умолчанию>, то при отсутствии фактического аргумента в строке вызова макрокоманды, соответствующий формальный аргумент в макрорасширении будет заменяться строкой_по_умолчанию.
Если имя формального параметра в тексте макроопределения непосредственно примыкает к какой-то строке, то используется префикс “&”.
4. Поддержка вызова смешанного программирования
а) Си+Ассемблер
_имя proc c near par1:тип, par2:тип,…
- объявляет имена
par1 equ [bp + смещ1]
par2 equ [bp + смещ2]
…
- создает фрагмент сохранения-инициализации BP
; addvl - сложение двух чисел переменной длины
; *y = *y + *x
; len - длина аргументов в словах
; x[0], y[0] - младшие слова
; При переполнении в AX возвращается -1, иначе 0
; В алгоритме сложения используется механизм
; автомодификации указателя SI в строковой команде
; Для доступа ко второму слагаемому используется
; этот же автомодифицируемый регистр SI в сумме [BX+SI]
; для чего BX содержит разность y-x-2
MASM
MODEL small
.code
public _addvl
_addvl proc c near x:word, y:word, len:word
; ------------------------------------------
; предыдущая строка эквивалентна строкам:
; _addvl proc near
; x equ [bp+8]
; y equ [bp+6]
; len equ [bp+4]
; push bp
; mov bp, sp
;-------------------------------------------
push si ; сохранение
push bx ; регистров
push cx ; для организации цикла
mov cx, len ; cx = len
mov si, x ; si = x
mov bx, y ; bx = y
sub bx, si ; bx = y-x
dec bx ;
dec bx ; y' = bx+si = --y
cld ; массив обрабатываем через *si++
xor ax, ax ; CF = 0
l0: lodsw ; ax = *x++; y'++
adc [bx+si], ax ; *y = ax
loop l0
mov ax, -1 ; учет переполнения
jo fin ;
xor ax, ax ; сброс признака переполн.
fin: pop cx
pop bx
pop si
ret
_addvl endp
end
#include <stdio. h>
#define LEN 5
extern int addvl(int *x, int *y, int len);
/********************************************
pri - печать длинного числа mn длиной len
слов с конца к началу в шестнадцатиричном
виде с предвыводом s_b и поствыводом s_e
*********************************************/
void pri(int *mn, int len, char *s_b,
char *s_e)
{ printf("%s",s_b);
for(mn += len; len>0; len--)
printf("%04x ", *--mn);
printf("%s\n",s_e);
} /* pri */
main()
{int a[LEN]={0x9932,0xFF24,3,4,0x7ffa};
int b[LEN]={6,5,4,3,2};
int n;
char *msg;
for(n=3; n>0;n--)
{ pri(a, LEN," ",""); /* вывод */
pri(b,LEN,"+ ",""); /* операндов */
if(addvl(a, b, LEN)==0) /* сложение */
msg = "OK\n";
else msg = "Overflow\n";
pri(b,LEN,"= ",msg); /* вывод результата */
}
return(0);
}
Команда сборки:
bcc - v - ms c&asm. c addvl. asm
Выходные данные программы:
7ffa 0004 0003 ff24 9932
+ 0002 0003 0004 0005 0006
= 7ffc 0007 0007 ff29 9938 OK
7ffa 0004 0003 ff24 9932
+ 7ffc 0007 0007 ff29 9938
= fff6 000b 000b fe4e 326a Overflow
7ffa 0004 0003 ff24 9932
+ fff6 000b 000b fe4e 326a
= 7ff0 000f 000f fd72 cb9c OK
5. Директивы условной трансляции
IFxxx
тело_условия_true
ENDIF
или
IFxxx
тело_условия_true
ELSE
тело_условия_false
ENDIF
В логических выражениях могут фигурировать отношения: EQ-равно, NE-не равно, LT-меньше, LE-меньше_или_равно, GT-больше, GE-больше_или_равно.
Значения логических выражений: 0 или -1
Операции: OR, AND, XOR, NOT. Задают поразрядные логические операции.
Основные директивы условной трансляции:
IF логическое_выражение – если истинно
IFE логическое_выражение – если ложно
IFDEF идентификатор – если идентификатор определен
IFNDEF идентификатор – если не определен
IFB строка – строка не пуста
IFNB строка – в строке есть не пробелы
IFIDN строка1,строка2 – строки идентичны
IFIDNI строка1,строка2 – строки идентичны с игнорированием разницы в регистрах
IFDIF строка1,строка2 – строки различны
IFDIFI строка1,строка2 – строки различны при игнорировании регистров
|
Из за большого объема этот материал размещен на нескольких страницах:
1 2 3 4 5 6 |




