мета-данные страницы
Загрузка не удалась. Возможно, проблемы с правами доступа?
Различия
Показаны различия между двумя версиями страницы.
Следующая версия | Предыдущая версия | ||
asm:second3 [03/03/2011 16:08] – создано arabusov | asm:second3 [26/02/2014 22:16] (текущий) – arabusov | ||
---|---|---|---|
Строка 1: | Строка 1: | ||
- | <code=c># | + | ===== Механизм связки Си-Ассемблер ===== |
- | #include "m6845.h" | + | На предыдущих уроках мы познакомились с гибридным программированием. В этом разделе будет дана теоретическая модель построения связи asm-c |
- | #include " | + | |
- | unsigned char __maxX (void) | + | Данный способ передачи параметров используется в языках программирования Си, Си++, Пролог и других. Этот метод противопоставлен методу языка Паскаль, |
- | { | + | |
- | if (! mode) | + | |
- | return 40; | + | |
- | else return 80; | + | |
- | } | + | |
- | int write (unsigned char * string) | + | Итак, если мы определим функцию в Си< |
- | { | + | <code=asm> push d |
- | int buf; | + | push c |
- | unsigned char ch; | + | push b |
- | int i=0; | + | push a |
- | attribut = 7; | + | call _foo |
- | while (*(string + i) != 0) | + | add sp,8 ;Освобождение стека осуществляется автоматически!</ |
- | { | + | При этом для правильного использования переданных параметров процедура //foo// может выглядеть так: |
- | update_cursor (cursor); | + | <code=asm>_foo proc |
- | if (cursor | + | |
- | { | + | |
- | scroll (); | + | |
- | cursor | + | |
- | } | + | |
- | if (*(string+i)>=32) | + | |
- | { | + | |
- | ch = *(string+i); | + | |
- | put_symbol (ch, | + | |
- | cursor++; | + | |
- | } | + | |
- | else | + | |
- | { | + | |
- | switch (*(string+i)) | + | |
- | { | + | |
- | case '\a': | + | |
- | case ' | + | |
- | cursor = cursor - buf + __maxX (); | + | |
- | if (cursor | + | |
- | { | + | |
- | scroll (); | + | |
- | cursor = (__maxY-1) * __maxX (); | + | |
- | } | + | |
- | break; | + | |
- | case 0: break; | + | |
- | default: cursor ++; | + | |
- | } | + | |
- | } | + | |
- | i++; | + | |
- | } | + | |
- | return 0; | + | |
- | }</code> | + | |
- | sdf | + | push bp |
+ | mov bp,sp | ||
- | <code=asm> | + | a = [bp+4] |
+ | b = [bp+6] | ||
+ | c = [bp+8] | ||
+ | d = [bp+10] | ||
- | _WIDTH equ 25 | + | ... |
- | L_1 equ 80 | + | pop bp |
- | L_0 equ 40 | + | ret |
- | public _put_symbol, _scroll | + | _foo endp</ |
+ | |||
+ | |||
+ | ==== Пример библиотеки, | ||
+ | |||
+ | Модуль Assembler | ||
+ | |||
+ | < | ||
+ | |||
+ | public _put_symbol | ||
extrn _cursor, _type_crt, _mode | extrn _cursor, _type_crt, _mode | ||
Строка 69: | Строка 44: | ||
_put_symbol proc near | _put_symbol proc near | ||
- | CLI | + | cli |
push bp | push bp | ||
mov bp,sp | mov bp,sp | ||
Строка 90: | Строка 65: | ||
pop bp | pop bp | ||
mov ax,0 | mov ax,0 | ||
- | STI | + | sti |
ret | ret | ||
_put_symbol endp | _put_symbol endp | ||
+ | end</ | ||
- | _scroll proc near | + | Заголовочный файл для предыдущего модуля |
- | CLI | + | < |
- | push bp | + | |
- | push ds | + | |
- | push si | + | |
- | push di | + | |
- | cmp _mode,0 | + | char type_crt = 1; /* Тип монитора. |
- | je mode0 | + | |
- | mov dh,L_1 | + | unsigned char mode = 03; /* Режим, очевидно */ |
- | jmp contin | + | |
- | mode0: | + | extern unsigned int cursor = 0; /* Позиция курсора в линейном режиме */ |
- | mov dh,L_0 | + | |
- | contin: | + | extern unsigned char attribut = 7; /* Его атрибут */ |
- | mov al,_WIDTH | + | extern int put_symbol (unsigned char symbol, unsigned char attribut);</ |
- | mul dh | + | |
- | sub al,dh | + | Обратите внимание на эти строки: |
- | mov cx,ax | + | < |
- | shl ax,1 | + | |
- | mov bp,ax | + | push bp |
- | cld | + | mov bp,sp |
- | mov bx,0b800h ; | + | ... |
+ | |||
+ | mov al,[bp+4] | ||
+ | mov ah,[bp+6] | ||
- | mov ds, | + | ... |
- | mov es, | + | |
- | xor bx,bx | + | |
- | mov di,bx | + | _put_symbol endp</ |
- | mov bl,dh | + | Это - передача параметров процедуре ассемблера без использования директивы ARG. |
- | shl bx,1 | + | |
- | mov si, | + | |
- | rep movsw | + | |
- | mov cl, | + | В модуле языка Си записано следующее: |
- | mov ax, | + | < |
+ | Это значит, | ||
+ | ==== Альтернативный вариант написания процедур на ассемблере ==== | ||
+ | Во многих ассемблерах (в том числе и TASM) встроена поддержка передачи параметров | ||
- | l2: | + | Пример: |
- | mov ds:[bp],ax | + | < |
- | inc bp | + | |
- | inc bp | + | |
- | dec cl | + | |
- | cmp cl,0 | + | |
- | jne l2 | + | |
- | xor ax,ax | + | ... |
- | pop di | ||
- | pop si | ||
- | pop ds | ||
- | pop bp | ||
- | STI | ||
ret | ret | ||
- | _scroll | + | _foo endp</ |
- | + | В данном методе нельзя использовать | |
- | end</ | + | |
- | + | ||
- | < | + | |
- | + | ||
- | char type_crt = 1; /* Тип монитора. 0 - MDA, 1 - CGA, EGA e t. c.*/ | + | |
- | + | ||
- | unsigned char mode = 03; /* Режим, очевидно */ | + | |
- | + | ||
- | #define __maxY 25 | + | |
- | + | ||
- | unsigned char __maxX (void); | + | |
- | + | ||
- | extern unsigned int cursor = 0; /* Позиция курсора в линейном режиме */ | + | |
- | + | ||
- | extern unsigned char attribut = 7; /* Его атрибут */ | + | |
- | + | ||
- | extern int put_symbol (unsigned char symbol, unsigned char attribut); | + | |
- | + | ||
- | extern int scroll (void); /* Прокручиваем экран на одну | + |