
- •Связь Ассемблера и Си
- •Void main()
- •Ограничения на встроенное ассемблирование.
- •Вызов функций, написанных на языке Ассемблера из Си-программ
- •Передача параметров в функциях Си
- •Вызов функций Си из программ на языке Ассемблера
- •Include macro.Inc
- •If type number eq 0
- •If number le 0fffFh
- •X dw 0fcd5h
- •Void main()
Вызов функций Си из программ на языке Ассемблера
При выполнении задания A5 мы испытывали неудобство, связанное с тем, что приходилось вручную переводить числа из 16-ричного представления в двоичное, чтобы убедиться в правильности промежуточных и конечных результатов. Хорошо бы поместить в программу отладочную печать в двоичном коде. Можно написать свою подпрограмму на языке Ассемблера для получения строки нулей и единиц, соответствующих нужному числу, это несложно. Но ещё проще воспользоваться библиотечными программами Си.
Нам понадобятся две функции:
itoa(value,string,radix), (integertoASCII), которая записывает valueв строку stringпредставление числа valueпо основанию radix
intstrlen(string) —возвращает длину строки
Вызов подпрограммы оформим в виде макроса.
.286 ; Разрешены инструкции 286-го процессора
Include macro.Inc
outbin MACRO number
If type number eq 0
If number le 0fffFh
mov ax, number
ELSE
%OUT Constant number is too large
EXITM
ENDIF
ELSEIF TYPE number EQ 1
mov al, number
mov ah, 0
ELSEIF TYPE number EQ 2
mov ax, number
ELSE
%OUT Invalid operand number
EXITM
ENDIF
call out_number
ENDM
.MODEL small
.STACK 100h
GLOBAL _itoa:PROC, _strlen:PROC
.DATA
b DB 43h ; Выводимые числа
X dw 0fcd5h
w DD 1
num DB 19 DUP(0) ; 16 байтов на число
; и ещё 3 байта на завершение строки
.CODE
out_number PROC ; В AX - выводимое число
push di ; используем DI
push 2 ; Основание системы счисления
push OFFSET num ; Строка для вывода
push ax ; Выводимое число
call _itoa ; itoa( value, string, radix)
add sp,6
push OFFSET num
call _strlen ; int strlen( string)
pop cx
mov di, OFFSET num
add di, ax ; Переместить на конец строки
mov word ptr [di], 0A0Dh
inc di
inc di
mov byte ptr [di], '$'
message num
pop di
ret
out_number ENDP
start: mov ax,@data
mov ds,ax
outbin b
outbin x
outbin 12345h
outbin w
exit
END start
Обратите внимание на использование символа подчёркивания перед именами библиотечных функций. В программе на языке Си подчёркиваний нет. Их автоматически добавляет компилятор. В этом можно убедиться, посмотрев ассемблерный файл для какой-нибудь программы на языке Си (воспользовавшись ключом -S), или в карте памяти.
Команды для получения exe-файла
tasm/mx outnum.asm
tlink -v outnum.obj,,,e:\tc_2plus\lib\cs
Конечно, хотелось бы ещё воспользоваться функцией printf. Но здесь нас подстерегает неудача. Компоновщик сообщит нам
Error: Undefined symbol _ERRNO in module IOERROR
Error: Undefined symbol __REALCVTVECTOR in module REALCVT
Оказывается, для правильной работы printfнужно обязательно присоединять головной модуль, для малой модели памяти этоc0s.obj. В нём и содержаться определения вышеупомянутых символов. Но мы не будем развивать эту тему.
Средства Ассемблера для интерфейса с языком Си.
Пример. Программа конкатенации двух строк. Сначала напишем головную программуtest.c.
#include <stdio.h>
unsigned int ConStr( char*, char*, char*);
#define MAX_SIZE 50