Turbo Assembler 3.0. Руководство пользователя

Пример обмена содержимого двух переменных


С помощью данной процедуры (VAREXCH.ASM) вы можете выполнить обмен содержимого двух переменных размера count. Если count имеет значение 0, то то процессор попытается перекопировать 64К.

CODE SEGMENT ASSUME cs:CODE,ds:NOTHING

; Параметры (заметим, что из-за push bp смещение ; увеличивается на 2)

var1 equ DWORD PTR ss:[bp+12] var2 equ DWORD PTR ss:[bp+8] count equ WORD PTR ss:[bp+6]

Exchange PROC FAR PUBLIC Exchange cld ; обмен в прямом направлении mov dx,ds ; сохранить регистр DS push bp mov bp,sp ; получить базу стека lds si,var1 ; получить первый адрес les di,var2 ; получить второй адрес mov cx,count ; получить число перемещаемых ; байт shr cx,1 ; получить счетчик слов ; (младший бит -> перенос) jnc ExchangeWord ; если не нечетный байт, ; войти в цикл mov al,es:[di] ; считать нечетный байт ; из var2 movsb ; переместить байт из var1 ; в var2 mov [si-1],al ; записать var2 в var1 jz Finis ; выполнено, если нужно ; выполнить обмен только ; одного байта ExchangeWords: mov bx,-2 ; BX - это удобное место ; для хранения -2 ExchangeLoop: mov ax,es:[di] ; считать слово из var2 movsw ; переместить из var1 ; в var2 mov [bx][si,ax ; записать слово var2 в ; var1 loop ExchangeLoop ; повторить count/2 раз Finis: mov ds,dx ; получить обратно DS ; Турбо Паскаля pop bp ret 10 Exchange ENDP CODE ENDS END

Программа Турбо Паскаля, которая использует функцию Exchange (файл varexch.pas), имеет вид:

program TextExchange;

type EmployeeRecord = record Name : string[30]; Address : string[30]; City : string[15]; State : string[2]; Zip : string[10]; end;

var OldEmployee, NewEmployee : EmployeeRecord;

{$F+}

procedure Exchange(var var1,var2; count : word); external; {$L XCHANGE.OBJ} {$F-} begin with OldEmployee do begin Name := 'John Smith'; Address := ' 123 F Street'; City := 'Scotts Valley'; State := 'CA'; Zip := ' 90000-0000'; end; with NewEmployee do begin Name := 'Mary Jones'; Address := ' 9471 41st Avenue'; City := 'New York'; State := 'NY'; Zip := ' 10000-1111'; end; Writeln('Before: ',OldEmployee.Name,' ',NewEmployee.Name); Exchange(OldEmployee,NewEmployee,sizeof(OldEmployee)); Writeln('After: ',OldEmployeeName,' ',NewEmployee.Name); Exchange(OldEmployee,NewEmployee,sizeof(OldEmployee)); Writeln('After: ',OldEmployeeName,' ',NewEmployee.Name); end.


Чтобы сформировать и запустить данные программы на Паскале и Ассемблере, используйте следующие команды командного файла:
TASM XCHANGE TPC XCHANGE XCHANGE
Если использовать директиву .MODEL, то программа Exchange на Ассемблере будет выглядеть следующим образом:
.MODEL large, PASCAL .CODE Exchange PROC FAR var1:DWORD,var2:DWORD,count:WORD PUBLIC Exchange cld ; обмен в прямом направлении mov dx,ds ; сохранить DS push bp mov bp,sp ; получить базу стека lds si,var1 ; получить первый адрес les di,var2 ; получить второй адрес mov cx,count ; получить число перемещаемых ; байт shr cx,1 ; получить счетчик слов ; (младший бит -> перенос) jnc ExchangeWord ; если не нечетный байт, ; войти в цикл mov al,es:[di] ; считать нечетный байт ; из var2 movsb ; переместить байт из var1 ; в var2 mov [si-1],al ; записать var2 в var1 jz Finis ; выполнено, если нужно ; выполнить обмен только ; одного байта ExchangeWords: mov bx,-2 ; BX - это удобное место ; для хранения -2 ExchangeLoop: mov ax,es:[di] ; считать слово из var2 movsw ; переместить из var1 ; в var2 mov [bx][si,ax ; записать слово var2 в ; var1 loop ExchangeLoop ; повторить count/2 раз Finis: mov ds,dx ; получить обратно DS ; Турбо Паскаля ret Exchage ENDP CODE ENDS END
Вы можете использовать ту же программу на Паскале и просто ассемблировать альтернативный вариант процедуры Exchаnge и пере- компилировать программу с помощью того же командного файла.

Содержание раздела