0

我正在使用 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
4

6 回答 6

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.

于 2013-05-14T20:38:02.537 回答
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
于 2013-05-15T08:03:52.047 回答
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

这样做的问题是检测和处理“字符串结尾”变得混乱,因为(在你的情况下)$字符可能以ALor结尾AH(取决于字符串是否有奇数或偶数个字符)。

当然有几种选择。第一种是将反转的字符串存储在带有填充的堆栈上,然后在删除填充的同时将其复制到其他地方。

另一种选择是在堆栈上保留足够的空间(例如从 中减去一个值SP),然后使用普通MOV指令(不使用PUSH)在您保留的空间中创建反转字符串。

于 2013-05-15T04:10:12.173 回答
0

据我所知,您不能将字节推送到堆栈上,只能推送单词和双字。这是一个想法:你有字符串,使用过程计算字符串长度,将字符串压入堆栈,将字符串长度 1 添加到 EBP(也就是说,如果直接在 EBP 之上,你有字符串,否则相应地对其进行操作),这现在将指向字符串的末尾。现在您可以使用 EBP 获取最后一个字符,然后减一并继续逐字符获取。

于 2013-05-15T17:32:55.353 回答
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
于 2013-05-15T17:21:01.377 回答
-2

You don't reverse the string, the stack does it for you

String DB "NAJAFI"

is pushed on like:

I <---first pop

F

A

J

A

N <--First push: stack pointer+2(or4)

So when you pop it you simply pop straight to a print function and it's reversed.

Magic !

于 2013-05-14T22:35:38.447 回答