Справочник функций

Ваш аккаунт

Войти через: 
Забыли пароль?
Регистрация
Информацию о новых материалах можно получать и без регистрации:

Почтовая рассылка

Подписчиков: -1
Последний выпуск: 19.06.2015

Связь ассемблера и паскаля на уровне объектного кода

10K
21 октября 2007 года
Shalfey
47 / / 10.03.2007
Постановка задачи:

В основной программе на языке высокого уровня (Паскаль) определить и инициализировать содержание исходного массива. Сформировать таблицу адресов данных передаваемых в процедуру.Организовать обращение к функции написанной на языке Ассемблер. Реализовать на языке ассемблера функцию, в соответствии с индивидуальным заданием. Вывести на экран полученные выходные данные средствами языка высокого уровня.

Проблема: приём параметров в асм-модуле от паскаль программы через таблицу адресов.

Код паскаль-модуля:
Код:
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

Далее необходимо через 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);


Меня смущает именно адресация передаваемых параметров (сегмент:смещение). Если можно приведите подробные комментарии. Заранее благодарен.
10K
11 ноября 2007 года
Shalfey
47 / / 10.03.2007
Задача осталась та же, но от формирования таблицы адресов параметров отказались. Зато предусмотрели также передачу константы в асм-модуль по значению. Поэтому, если ещё кому-то нужно, я привожу исходные тексты правильно работающей программы:

Код Паскаль-модуля:
Код:
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.

Код асм-модуля:
Код:
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
Реклама на сайте | Обмен ссылками | Ссылки | Экспорт (RSS) | Контакты
Добавить статью | Добавить исходник | Добавить хостинг-провайдера | Добавить сайт в каталог