program main;
const
n_elem : byte = 50;
n_params : byte = 6;
type
table = array[1..n_params];
var
tbl : table;
arr : array [1..n_elem] of word;
sum : word = 0;
i : byte;
Procedure f1(var t : table); external;
begin
{$L lb7}
writeln('This program finds the sum of elements in'
' which bits 2 and 10 are different');
for i := 1 to n_elem do begin
write('Please, enter the value of ', i, ' element: ');
readln(arr);
end;
tbl[1] := ofs(arr);
tbl[3] := ofs(n_elem);
tbl[5] := ofs(sum);
tbl[2] := seg(arr);
tbl[4] := seg(n_elem);
tbl[6] := seg(sum);
wrieln('Returning to the assembler function...');
f1(tbl);
writeln('Sum of elements is ', sum);
end.
Связь ассемблера и паскаля на уровне объектного кода
В основной программе на языке высокого уровня (Паскаль) определить и инициализировать содержание исходного массива. Сформировать таблицу адресов данных передаваемых в процедуру.Организовать обращение к функции написанной на языке Ассемблер. Реализовать на языке ассемблера функцию, в соответствии с индивидуальным заданием. Вывести на экран полученные выходные данные средствами языка высокого уровня.
Проблема: приём параметров в асм-модуле от паскаль программы через таблицу адресов.
Код паскаль-модуля:
Код:
В асм-модуле нужно сохранить значения регистров в стэк и принять параметры. Как извлечь из стэка адреса параметров, учитывая дальнюю модель вызова асм-процедуры(сегмент:смещение)? Предположим, асм-модуль начинается так:
Код:
data segment
mask_2 dw 100b
mask_10 dw 10000000000b
summa dw 0
data ends
stak segment
dw 20 dup (0)
stak ends
code segment
assume cs:code, ds:data, ss:stak
public f1
f1 proc far
push bp
push ax
push bx
push cx
push dx
push si
push di
push es
mov ax, data
mov ds, ax
mov bp, sp
mask_2 dw 100b
mask_10 dw 10000000000b
summa dw 0
data ends
stak segment
dw 20 dup (0)
stak ends
code segment
assume cs:code, ds:data, ss:stak
public f1
f1 proc far
push bp
push ax
push bx
push cx
push dx
push si
push di
push es
mov ax, data
mov ds, ax
mov bp, sp
Далее необходимо через bp запихнуть в si адрес начала массива (arr), в summa - значение из sum. Как это сделать?
Обязательное условие: параметры из паскаль-модуля передавать именно в виде:
Код:
tbl[1] := ofs(arr);
tbl[3] := ofs(n_elem);
tbl[5] := ofs(sum);
tbl[2] := seg(arr);
tbl[4] := seg(n_elem);
tbl[6] := seg(sum);
f1(tbl);
tbl[3] := ofs(n_elem);
tbl[5] := ofs(sum);
tbl[2] := seg(arr);
tbl[4] := seg(n_elem);
tbl[6] := seg(sum);
f1(tbl);
Меня смущает именно адресация передаваемых параметров (сегмент:смещение). Если можно приведите подробные комментарии. Заранее благодарен.
Код Паскаль-модуля:
Код:
program main;
uses crt;
const
num_elem = 50;
type
massiv = array[1..num_elem] of word;
var
a : massiv;
s : word;
code : integer;
i, j : byte;
str : string;
{$F+}
{$L lb7.obj}
procedure f1(var arr : massiv; const n_elem : byte; var sum : word); external;
begin
writeln('This program finds the sum of elements in which bits 2 and 10 are different.');
writeln('Enter "000" to fill the rest of array with zeros.');
for i := 1 to num_elem do begin
write('Please, enter the value of ', i, ' element: ');
readln(str);
if str <> '000' then begin
val(str, a, code);
if code <> 0 then a := 0;
end else begin
for j := i to num_elem do a[j] := 0;
break;
end;
end;
writeln('Calling the assembler function...');
f1(a, num_elem, s);
writeln('Sum of elements is ', s);
end.
uses crt;
const
num_elem = 50;
type
massiv = array[1..num_elem] of word;
var
a : massiv;
s : word;
code : integer;
i, j : byte;
str : string;
{$F+}
{$L lb7.obj}
procedure f1(var arr : massiv; const n_elem : byte; var sum : word); external;
begin
writeln('This program finds the sum of elements in which bits 2 and 10 are different.');
writeln('Enter "000" to fill the rest of array with zeros.');
for i := 1 to num_elem do begin
write('Please, enter the value of ', i, ' element: ');
readln(str);
if str <> '000' then begin
val(str, a, code);
if code <> 0 then a := 0;
end else begin
for j := i to num_elem do a[j] := 0;
break;
end;
end;
writeln('Calling the assembler function...');
f1(a, num_elem, s);
writeln('Sum of elements is ', s);
end.
Код асм-модуля:
Код:
code segment
assume cs:code
public f1
mask_2 dw 100b
mask_10 dw 10000000000b
summa dw 0
f1 proc far
push bp
mov bp, sp
push ax
push bx
push cx
push dx
push si
mov cx, [bp+10] ; num_el
mov si, [bp+6]
push word ptr [si] ; sum
pop summa
les si, [bp+12] ; addr arr
cycle:
mov ax, [si]
mov dx, [si]
mov bx, [si]
and ax, cs:mask_2
and dx, cs:mask_10
shr dx, 8
cmp ax, dx
je equal
add summa, bx
equal:
add si, 2
loop cycle
mov si, [bp+6]
push summa
pop word ptr [si]
pop si
pop dx
pop cx
pop bx
pop ax
pop bp
ret 0Ah
f1 endp
code ends
end
assume cs:code
public f1
mask_2 dw 100b
mask_10 dw 10000000000b
summa dw 0
f1 proc far
push bp
mov bp, sp
push ax
push bx
push cx
push dx
push si
mov cx, [bp+10] ; num_el
mov si, [bp+6]
push word ptr [si] ; sum
pop summa
les si, [bp+12] ; addr arr
cycle:
mov ax, [si]
mov dx, [si]
mov bx, [si]
and ax, cs:mask_2
and dx, cs:mask_10
shr dx, 8
cmp ax, dx
je equal
add summa, bx
equal:
add si, 2
loop cycle
mov si, [bp+6]
push summa
pop word ptr [si]
pop si
pop dx
pop cx
pop bx
pop ax
pop bp
ret 0Ah
f1 endp
code ends
end