使用堆栈反转字符串

时间:2013-05-14 20:08:06

标签: assembly

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

6 个答案:

答案 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

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

当然有几种选择。第一种方法是使用填充将反向字符串存储在堆栈中,然后在删除填充时将其复制到其他位置。

另一种方法是在堆栈上保留足够的空间(例如从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)

所以当你弹出它时,你只需直接弹出打印功能就可以了。它反过来了。

魔术!