assembly - Intel 8086 - 反转数组或向后循环
问题描述
我一直在尝试编写一个以两种方式反转数组内容的代码。我已经使用 push 和 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
并向上移动。
该代码将使用 DOS.PrintString 函数 09h 一次性打印结果。stosb
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
接下来是一次读取和写入 2 个元素的优化。
当然,这仅在使用一定长度的数组时才重要,因此在有限的 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
推荐阅读
- android - 为什么我的广播接收器无法检测到 USB 连接?
- powerbi - 如何根据我在power bi中的期间代码获取最近三个月的滚动金额?
- node.js - 如何将标准搜索分析器与关键字映射一起使用?
- reactjs - React Reducer - 从状态中获取价值
- android-10.0 - Android 10:如何检查收到的文件路径是否是应用程序特定目录中的文件路径(getExternalFilesDir)
- javascript - NodeJS将数据从流发送到前端(ReactJS)
- ios - 为什么我的自定义 UICollectionViewCell 没有显示?
- php - yii1 restful api中的post方法为空
- unit-testing - 在 Robot Framework 中将列表缩短为 n 个元素的最简单方法
- xamarin.forms - 将 AutomationProperties 设置为导航栏的后退按钮,以避免 TalkBack 的“未标记按钮”