我一直在尝试编写代码,以两种方式反转数组的内容。我已经用push and pop的方法做对了,但是我不知道怎么用指针的方法。
我希望你能解释清楚。
.model small
.data
tab db '12345' ,13,10,'$'
.code
main proc
mov ax,@data
mov ds,ax
mov si,offset tab
mov di,offset tab+5
mov cx,5
etiq1:
mov bx,[si]
push bx
inc si
loop etiq1
mov cx,5
etiq2:
pop dx
mov ah,02h
int 21h
loop etiq2
main endp
end main
通过堆栈反转字符串数组并使用字符串原语lodsb
和stosb
。
push-loop和pop-loop在遇到终止字符串的回车符时结束。
需要CLD
指令使lodsb
和stosb
在内存中向上移动。
代码将在DOS上一次性打印结果。PrintString函数
mov ax, @data
mov ds, ax
mov di, offset tab
mov si, di
mov dx, di
cld
etiq1:
lodsb
push ax
cmp byte ptr [si], 13
jne etiq1
etiq2:
pop ax
stosb
cmp byte ptr [di], 13
jne etiq2
mov ah, 09h ; DOS.PrintString
int 21h
mov ax, 4C00h ; DOS.Terminate
int 21h
使用指针反转数组的另一种方法。
左边的元素使用SI
指针读写,右边的元素使用相同的指针读写,但偏移了适当的量。
只要这个偏移量大于零,循环就可以继续。如果两个地址要与不同的字节通信,那么偏移量必须至少为1。在内存中。
mov ax, @data
mov ds, ax
mov si, offset tab
mov bx, 4 ; 5 elements : last element is at offset 4 from the first element
More:
mov al, [si] ; Read on left side
mov dl, [si+bx] ; Read on right side
mov [si], dl ; Write on left side
mov [si+bx], al ; Write on right side
inc si ; Move to the right
sub bx, 2 ; Next couple of elements is 2 bytes closer to each other
ja More ; Must stay above 0 to address different elements
; Here BX is -1, or 0 for remaining 0, or 1 element
mov dx, offset tab
mov ah, 09h ; DOS.PrintString
int 21h
mov ax, 4C00h ; DOS.Terminate
int 21h
下一步是一次读写两个元素的优化。
这当然只有在处理一定长度的数组时才重要,所以在有限的5字节数组中不重要!这一次,偏移量必须至少为3,这样两个地址才能与不同的字通信。在内存中。
mov ax, @data
mov ds, ax
mov si, offset tab
mov bx, NumberOfByteSizedElementsMinusOne
jmp Begin
More:
mov ax, [si] ; Read pair on left side
mov dx, [si+bx-1] ; Read pair on right side
xchg al, ah
xchg dl, dh
mov [si], dx ; Write pair on left side
mov [si+bx-1], ax ; Write pair on right side
add si, 2 ; Move to the right
sub bx, 4 ; Next couple of paired elements is 4 bytes closer to each other
Begin:
cmp bx, 3
jge More ; Must stay above 2 to address different paired elements
; Here BX is -1, 0, 1, or 2 for remaining 0, 1, 2, or 3 elements
cmp bx, 0
jle Done
mov al, [si] ; Read on left side
mov dl, [si+bx] ; Read on right side
mov [si], dl ; Write on left side
mov [si+bx], al ; Write on right side
Done:
mov dx, offset tab
mov ah, 09h ; DOS.PrintString
int 21h
mov ax, 4C00h ; DOS.Terminate
int 21h