мета-данные страницы
Загрузка не удалась. Возможно, проблемы с правами доступа?
Различия
Показаны различия между двумя версиями страницы.
| Следующая версия | Предыдущая версия | ||
| 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); /* Прокручиваем экран на одну | + | |