С помощью данной процедуры (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.