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