Примеры подпрограмм на Ассемблере для Турбо Паскаля
В данном разделе вы дадим некоторые примеры подпрограмм на языке Ассемблера, которые вы можете вызывать из программ Турбо Паскаля.
Подпрограмма шестнадцатиричного преобразования общего назначения
Содержащиеся в параметре num байты преобразуются в строку шестнадцатиричных цифр длины (byteCount * 2). Поскольку каждый байт порождает два символа, максимальное значение byteCount равно 127 (не проверяется). Для преобразования каждой группы (по 4 бита) в шестнадцатиричную цифру мы для скорости используем последовательность add-daa-adc-daa.
Процедура HexStr (ее можно найти в файле HEX.ASM) написана так, что вызываться она должна с помощью вызова дальнего типа. Это означает, что ее следует описывать в интерфейсной части модуля Турбо Паскаля или с помощью директивы компилятора {$F+}.
CODE SEGMENT ASSUME cs:CODE,ds:NOTHING
; Параметры (+2 с учетом push bp)
byteCount equ byte ptr ss:[bp+6] num equ dword ptr ss:[bp+8]
; Адресация к результату функции (+2 с учетом push bp)
resultPtr equ dword ptr ss:[bp+12]
HexStr PROC FAR PUBLIC HexStr
push bp mov bp,sp ; получить указатель стека les di,resultPtr ; получить адрес результата функции mov dx,ds ; сохранить DS Турбо Паскаля в DX lds si,sum ; получить адрес числа mov al,byteCount ; сколько байт? xor ah,ah ; слово mov cx,ax ; отслеживать число байт в CX add si,ax ; начать со старшего байта числа dec si shl ax,1 ; сколько цифр? (2/байт) cld ; сохранить число цифр (работать в прямом направлении) stosb ; в приемнике - байт длины строки NextLoop: std ; сканировать число от старшего байта к младшему lodsb ; получить следующий байт mov ah,al ; сохранить его shr al,1 ; выделить старшую группу бит shr al,1 shr al,1 shr al,1 add al,90h ; специальная после довательность шестнад- ; тиричного преобразования daa ; использование инструкций ADD и DAA adc al,40h daa ; группа преобразована в код ASCII cld ; сохраним ASCII и следуем далее stosb mov al,ah ; повторить преобразование для младшей группы and al,0Fh add al,90h daa adc al,40h daa stosb loop HexLoop ; продолжать, пока не будет выполнено mov ds,dx pop bp ret 6 ; параметры занимают 6 байт HexStr ENDP CODE ENDS END
Пример программы на Паскале, где используется функция HexStr, имеет следующий вид:
Program HexTest; var num : word;
{$F+}
function HexStr(var num; byteCount : byte) : string; external;
{$L HEXSTR.OBJ}
{$F-} begin num := word; Writeln("Преобразованная строка имеет шестнадцатиричное представление: ", HexStr(num,Sizeof(num)),"*"); end.
Для построения и запуска примеров программы на Паскале и программы Ассемблера используйте следующие команды командного файла:
TASM HEXSTR TPC HEXTEST HEXTEST
Если вы используете директиву .MODEL, то программу HexStr можно записать следующим образом (файл HEXMOD.ASM):
.MODEL large, PASCAL .CODE HexStr PROC FAR num:DWORD,byteCount:BYTE RETURNS resultPtr:DWORD PUBLIC HexStr les di,resultPtr ; получить адрес результата функции mov dx,ds ; сохранить DS Турбо Паскаля в DX lds si,sum ; получить адрес числа mov al,byteCount ; сколько байт? xor ah,ah ; слово mov cx,ax ; отслеживать число байт в CX add si,ax ; начать со старшего байта числа dec si shl ax,1 ; сколько цифр? (2/байт) cld ; сохранить число цифр (работать в прямом направлении) stosb ; в приемнике - байт длины строки NextLoop: std ; сканировать число от старшего байта к младшему lodsb ; получить следующий байт mov ah,al ; сохранить его shr al,1 ; выделить старшую группу бит shr al,1 shr al,1 shr al,1 add al,90h ; специальная после довательность шестнад- ; тиричного преобразования daa ; использование инструкций ADD и DAA adc al,40h daa ; группа преобразована в код ASCII cld ; сохраним ASCII и следуем далее stosb mov al,ah ; повторить преобразование для младшей группы and al,0Fh add al,90h daa adc al,40h daa stosb loop HexLoop ; продолжать, пока не будет выполнено mov ds,dx ; восстановить DS Турбо Паскаля ret HexStr ENDP CODE ENDS END
При этом вы можете использовать ту же программу на Паскале и просто ассемблировать альтернативный вариант HexStr и перекомпилировать программу с помощью того же командного файла.
1 2 3 4 5 6 7 8
8 8 8
|