===== Механизм связки Си-Ассемблер ===== На предыдущих уроках мы познакомились с гибридным программированием. В этом разделе будет дана теоретическая модель построения связи 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!