мета-данные страницы
  •  
Загрузка не удалась. Возможно, проблемы с правами доступа?

Различия

Показаны различия между двумя версиями страницы.

Ссылка на это сравнение

Следующая версия
Предыдущая версия
asm:second3 [03/03/2011 16:08] – создано arabusovasm:second3 [26/02/2014 22:16] (текущий) arabusov
Строка 1: Строка 1:
-<code=c>#include "crt.h" +===== Механизм связки Си-Ассемблер ===== 
-#include "m6845.h" +На предыдущих уроках мы познакомились с гибридным программированиемВ этом разделе будет дана теоретическая модель построения связи asm-c
-#include "cursor.h"+
  
-unsigned char __maxX (void) +Данный способ передачи параметров используется в языках программирования Си, Си++, Пролог и других. Этот метод противопоставлен методу языка Паскаль, поэтому связка asm-pascal будет выглядеть по-другому!
-+
- if (mode) +
- return 40; +
- else return 80; +
-}+
  
-int write (unsigned char * string) +Итак, если мы определим функцию в Си<code=c>int foo (int a,int b,int c,int d);</code>то при вызове функции выполнятся следующие машинные инструкции: 
-+<code=asm> push d 
- int buf; + push c 
- unsigned char ch; + push b 
- int i=0; + push
- attribut = 7; + call _foo 
- while (*(string + i) != 0) + add sp,8 ;Освобождение стека осуществляется автоматически!</code
-+При этом для правильного использования переданных параметров процедура //foo// может выглядеть так
- update_cursor (cursor); +<code=asm>_foo proc
- if (cursor >= (__maxX () * __maxY)) +
- +
- scroll (); +
- cursor (__maxY-1) * __maxX (); +
-+
- if (*(string+i)>=32) +
- { +
- ch = *(string+i); +
- put_symbol (ch,attribut); +
- cursor++; +
-+
- else +
-+
- switch (*(string+i)) +
-+
- case '\a': +
- case '\n': buf = cursor % __maxX (); +
- cursor = cursor - buf + __maxX (); +
- if (cursor >= (__maxX ()* __maxY)) +
- +
- scroll (); +
- cursor = (__maxY-1) * __maxX (); +
-+
- break; +
- case 0break; +
- default: cursor ++; +
-+
-+
- i++; +
-+
- return 0; +
-}</code>+
  
-sdf+ push bp 
 + mov bp,sp
  
-<code=asm>.MODEL small+[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</code> 
 + 
 + 
 +==== Пример библиотеки, которая выводит символ на экран ==== 
 + 
 +Модуль Assembler 
 + 
 +<code=asm>.MODEL small 
 + 
 +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</code>
  
-_scroll proc near+Заголовочный файл для предыдущего модуля
  
- CLI +<code=c>/* Хидерный файл контроллера Motorola 6845 */
- push bp +
- push ds +
- push si +
- push di+
  
- cmp _mode,0 +char type_crt = 1; /* Тип монитора. - MDA, 1 - CGA, EGA e t.c.*/
- 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 symbolunsigned char attribut);</code>
- mul dh+
  
- sub al,dh +Обратите внимание на эти строки: 
- mov cx,ax +<code=asm>_put_symbol proc near 
- 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,bx ;DS:SI = 0b800h:0000H +        ... 
- mov es,bx ;ES:DI = 0b800h:0019H +        pop     bp 
- xor bx,bx +         
- mov di,bx +_put_symbol endp</code> 
- mov bl,dh +Это - передача параметров процедуре ассемблера без использования директивы ARG.
- shl bx,1 +
- mov si,bx +
- rep movsw+
  
- mov cl,dh ; здесь тоже проблема: не получается стереть +В модуле языка Си записано следующее: 
- mov ax,0720H ; нижнюю строчкуостаётся мусор+<code=c>extern int put_symbol (unsigned char symbol, unsigned char attribut);</code> 
 +Это значит, что передаваемые параметры начинались с адреса bp+4 
 +==== Альтернативный вариант написания процедур на ассемблере ==== 
 +Во многих ассемблерах (в том числе и TASM) встроена поддержка передачи параметров с использованием директивы //ARG// или усложнённой директивы //proc//
  
-l2+Пример
- mov ds:[bp],ax +<code=asm>_foo proc C, awordb: wordc: word, d: word
- inc bp +
- inc bp +
- dec cl +
- cmp cl,+
- jne l2+
  
- xor ax,ax+ ...
  
- pop di 
- pop si 
- pop ds 
- pop bp 
- STI 
  ret  ret
  
-_scroll endp +_foo endp</code> 
- +В данном методе нельзя использовать регистр BP!
-end</code> +
- +
-<code=c>/* Хидерный файл контроллера Motorola 6845 */ +
- +
-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); /* Прокручиваем экран на одну строчку */</code>+