мета-данные страницы
Механизм связки Си-Ассемблер
На предыдущих уроках мы познакомились с гибридным программированием. В этом разделе будет дана теоретическая модель построения связи asm-c
Данный способ передачи параметров используется в языках программирования Си, Си++, Пролог и других. Этот метод противопоставлен методу языка Паскаль, поэтому связка asm-pascal будет выглядеть по-другому!
Итак, если мы определим функцию в Си
int foo (int a,int b,int c,int d);
то при вызове функции выполнятся следующие машинные инструкции:
push d push c push b push a call _foo add sp,8 ;Освобождение стека осуществляется автоматически!
При этом для правильного использования переданных параметров процедура foo может выглядеть так:
_foo proc push bp mov bp,sp a = [bp+4] b = [bp+6] c = [bp+8] d = [bp+10] ... pop bp ret _foo endp
Пример библиотеки, которая выводит символ на экран
Модуль Assembler
.MODEL small public _put_symbol extrn _cursor, _type_crt, _mode .CODE _put_symbol proc near cli push bp mov bp,sp mov cx,_type_crt cmp cx,0 je _monocrome mov dx,0b800h jmp _continue _monocrome: mov dx,0b000h _continue: mov es,dx mov bx,_cursor shl bx,1 mov al,[bp+4] mov ah,[bp+6] mov es:[bx],ax pop bp mov ax,0 sti ret _put_symbol endp end
Заголовочный файл для предыдущего модуля
/* Хидерный файл контроллера Motorola 6845 */ char type_crt = 1; /* Тип монитора. 0 - MDA, 1 - CGA, EGA e t.c.*/ unsigned char mode = 03; /* Режим, очевидно */ extern unsigned int cursor = 0; /* Позиция курсора в линейном режиме */ extern unsigned char attribut = 7; /* Его атрибут */ extern int put_symbol (unsigned char symbol, unsigned char attribut);
Обратите внимание на эти строки:
_put_symbol proc near push bp mov bp,sp ... mov al,[bp+4] mov ah,[bp+6] ... pop bp _put_symbol endp
Это - передача параметров процедуре ассемблера без использования директивы ARG.
В модуле языка Си записано следующее:
extern int put_symbol (unsigned char symbol, unsigned char attribut);
Это значит, что передаваемые параметры начинались с адреса bp+4
Альтернативный вариант написания процедур на ассемблере
Во многих ассемблерах (в том числе и TASM) встроена поддержка передачи параметров с использованием директивы ARG или усложнённой директивы proc
Пример:
_foo proc C, a: word, b: word, c: word, d: word ... ret _foo endp
В данном методе нельзя использовать регистр BP!