汇编x86 32位/反向并追加字符串

时间:2011-12-03 13:18:59

标签: assembly x86 x86-64

我想在Assembly x-86中反转字符串。意思是 - 如果我得到“1234”,我想我的结果将是“4321”。我想把每个char都推到堆栈中,弹出它们。但我不知道要实现这个。我需要一个缓冲区吗? (我可以覆盖原始字符串)。

3 个答案:

答案 0 :(得分:2)

这样的东西可以工作(假设32位模式,使用NASM语法编写):

; finding string length:
mov ebx, mystr ; current position within the string
mov ecx, 0 ; current string length

l1:
mov al, [ebx] ; fetch a character from the string
cmp al, 0 ; is this string end?
je l2 ; yes, it is

inc ebx ; increment the position from where we'll read next character
inc ecx ; increment length
jmp l1 ; repeat

l2: ; ecx = string length

; reversing the string:
cmp ecx, 2 ; is the string too short?
jb l4 ; yes, it has 0 or 1 chars, we're done

mov ebx, mystr ; ebx points to the first char in the string
lea edx, [ebx+ecx-1] ; edx = ebx+ecx-1 - points to the last char in the string
shr ecx, 1 ; ecx = half the string length

l3:
mov al, [ebx]
xchg al, [edx]
mov [ebx], al ; [ebx] and [edx] swapped
inc ebx ; advance head pointer
dec edx ; advance tail pointer
loop l3 ; decrement ecx and if ecx isn't 0, repeat

l4:
;...

; string (NULL-terminated):
mystr db '1','2','3','4',0

答案 1 :(得分:1)

您可以使用其中一种抽象数据类型(例如堆栈或队列)执行此操作,但为什么要这么做呢?

只需使用两个指针,一个在开头,一个在最后,然后交换它们指向的内容。增加开始指针并递减结束,然后继续前进,直到它们相遇或交叉。

在下面的代码中(伪代码,因为(1)这听起来有点像家庭作业和(2)它很容易转换成任何程序语言),我会假设C风格的字符串,但你可以合理地调整其他变种容易。假设您可以访问值address of first character

,假设代码如下所示就足够了
set pstart to address of first character

# Locate last character
set pend to pstart
while [pend] is not null:
    pend = pend + 1
pend = pend - 1

# Continue until they cross
while pstart < pend:
    # Swap contents
    tmp = [pstart]
    [pstart] = [pend]
    [pend] = tmp

    # Move pointers
    pstart = pstart + 1
    pend = pend - 1

如果确实想要使用ADT,则堆栈就足以满足以下逻辑:

# Push until reached end of string
set pchar to address of first character
while [pchar] is not null:
    push [pchar]
    pchar = pchar + 1

# Then pop the same way (but reverse order)
set pchar to address of first character
while [pchar] is not null:
    pop [pchar]
    pchar = pchar + 1

答案 2 :(得分:0)

不确定你是如何跟踪原始字符串的,但我之前做过类似的事情。假设您正在接受键盘输入,最简单(但不是速度最佳)的方法是使用缓冲区,使用默认方向标志进入缓冲区,然后在输入完成后,翻转方向标志,设置寄存器然后lodsb ...根据字符串的来源,根据需要进行调整。