我正在使用dosbox,这是一项任务。我必须使用堆栈来反转字符串。我的想法是将字符串一次一个字符推入堆栈然后逐个弹出到RevString中。我无法弄清楚如何实际做到这一点。这是我到目前为止所拥有的。
.MODEL SMALL
.STACK 100h
.DATA
String DB "NAJAFI", 13, 10, "$"
RevString DB 6 DUP(?), '.', 13, 10, "$"
.CODE
Main PROC
;; Set up ds register to point to the data
mov ax, @data
mov ds, ax
;; printing a string in dos
mov dx, OFFSET String
mov ah, 9h
int 21h
;; reverse the string by using the stack
mov ax, WORD PTR String
push ax
pop ax
;mov RevString, ax
;; print the reverse string in dos
mov dx, RevString
mov ah, 9h
int 21h
;; DOS return
mov al, 0
mov ah, 4ch
int 21h
Main ENDP
END Main
答案 0 :(得分:1)
将字符串压入堆栈:
mov di, offset String
mov cx, string_length
xor ax, ax
pushloop:
mov al, [di]
push ax
inc di
dec cx
jnz pushloop
您可以执行相同类型的操作,将堆栈中的字符弹出到RevString
。
答案 1 :(得分:0)
对于80x86,堆栈在2字节,4字节或8字节边界上对齐(16位的2字节对齐)。如果你按一个字节,CPU将自动添加填充以确保对齐。
要解决这个问题,你可以改为推文。例如:
lodsw ;ax = next pair of bytes
rol ax,8 ;Swap the bytes
push ax ;Store the bytes
问题在于检测和处理“字符串结尾”会变得混乱,因为(在您的情况下)$
字符可能会以AL
或AH
结尾(取决于关于字符串是否有奇数或偶数个字符。)
当然有几种选择。第一种方法是使用填充将反向字符串存储在堆栈中,然后在删除填充时将其复制到其他位置。
另一种方法是在堆栈上保留足够的空间(例如从SP
中减去一个值),然后使用普通MOV
指令在您保留的空间中创建反向字符串(不使用{ {1}})。
答案 2 :(得分:0)
如果您不确定最新情况,那么您的字符串处理也太复杂了
创建有界数据块,使事情变得简单和动态
.start
db "NAJAFI"
.end
mov edx,end-start ;a nice and simple string length
mov ebx,start ;a nice and simple string start point
mov ecx,0
.loadstack
mov eax,[ebx]
push eax
inc ecx
cmp ecx,edx
jz printsetup
inc ebx
jmp loadstack
.printsetup
mov ecx,0
.printstackbackwards
pop eax
[PRINT IT OUT BIT]
inc ecx
cmp ecx,edx
jnz printstackbackwards
end
答案 3 :(得分:0)
因为我想尝试一下,这是我的版本。我在想是否可以优化它。
;**********************************************
;
; Reverse a string using the stack.
; EAX is the pointer to the C string.
ReverseWithStack proc
mov esi, eax
mov edi, eax
_push_loop:
mov al, [esi]
cmp al, 0
jz _pop_loop
push ax
inc esi
jmp _push_loop
_pop_loop:
mov al, [edi]
cmp al, 0
jz _done
pop ax
mov [edi], al
inc edi
jmp _push_loop
_done:
ret
ReverseWithStack ENDP
答案 4 :(得分:0)
据我所知,你不能在堆栈上推送字节,只能用单词和双字。 这是一个想法: 你有字符串, 使用过程计算字符串长度, 把字符串推到堆栈上, 将字符串length-1添加到EBP(也就是说,如果直接在EBP之上,你有字符串,否则相应地操纵它), 现在,这将指向字符串的结尾。现在您可以使用EBP获取最后一个字符,然后递减1并继续按字符逐个获取。
答案 5 :(得分:-2)
您不会反转字符串,堆栈会为您执行
String DB“NAJAFI”
按下就像:
I< --- first pop
˚F
A
Ĵ
A
N< - 首先推送:堆栈指针+ 2(或4)
所以当你弹出它时,你只需直接弹出打印功能就可以了。它反过来了。
魔术!