【问题标题】:Swapping first and last characters of string results in seg fault交换字符串的第一个和最后一个字符会导致段错误
【发布时间】:2021-02-19 16:13:03
【问题描述】:

我的目标是将x86-assembly 中字符串some_str 的第一个字符与最后一个字符交换。

这是我的尝试:

; assemble and link with:
; nasm -f elf32 -g test.asm && ld -melf_i386 test.asm.o -o test


section .text
global  _start
extern printf

_start:
    mov eax, some_str

    _loop:
    mov  di, [eax + 4]  ; ptr to end char
    mov  si, [eax]  ; ptr to start char

    mov  dl, [di]      ; DL = end char
    mov  al, [si]      ; AL = start char

    mov  [si], dl      ; start char = end char 
    mov  [di], al      ; end char = char 1 


    mov edx, len
    mov ecx, eax
    mov ebx, 1
    mov eax, 4
    int 0x80

    ret

    mov eax, 1
    int 0x80

section  .data
    some_str     db `abcd`, 0xa
    len     equ $ - some_str

出于某种原因,我忘记了这些台词:

    mov  dl, [di]      ; DL = end char
    mov  al, [si]      ; AL = start char

导致程序导致分段错误。

预期的标准输出是:

dbca

实际标准输出:

Segmentation fault (core dumped)`

我有什么遗漏吗?如何更正此代码以正确交换 some_str 的第一个和最后一个字符。

【问题讨论】:

  • 1.当您希望它们具有指针时,看起来您正在将字节加载到 disi 中。 2. 如果您使用的是 32 位,那么您应该使用 esiedi,因为指针是 32 位宽的。 3. 在调试器中单步查看寄存器中的值,你肯定会发现一些不对劲的地方。

标签: string parsing assembly x86 cpu-registers


【解决方案1】:

您的代码似乎在做一些比必要的复杂得多的事情。在mov eax, some_str 之后,eax 指向要交换的字节之一,eax+4 指向另一个。因此,只需将它们加载到两个 8 位寄存器中,然后以相反的方式将它们存储回来。

mov eax, some_str
mov cl, [eax]
mov dl, [eax + 4]
mov [eax + 4], cl
mov [eax], dl

你已经完成了,可以继续写出结果了。

请注意,不必先将指针加载到eax;你也可以这样做

mov cl, [some_str]
mov dl, [some_str + 4]
mov [some_str + 4], cl
mov [some_str], dl

如果你真的想让两个不同的寄存器指向两个不同的字节:首先,它们需要是 32 位寄存器。尝试使用 16 位寄存器si, di 在 32 位模式下寻址内存实际上是行不通的。其次,mov edi, [eax] 将在eax 位置加载内存内容edi,这是字符串的一些字节,而不是指针。您只需要mov edi, eax。对于第二个,您可以使用lea 进行有效地址计算的算术运算,但保留结果指针而不是进行加载。所以我认为将你的代码变成原始(低效)精神但正确的方法是

mov edi, eax
lea esi, [eax+4]
mov dl, [edi]
mov al, [esi]
mov [esi], dl
mov [edi], al

【讨论】:

  • 有什么好的参考资料可以参考我来学习x86-assembly,比如书籍等?我真的很感谢你的帮助,我真的很努力学习。
  • @dnsis_445:查看stackoverflow.com/tags/x86/info
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-06-17
  • 1970-01-01
  • 2013-12-23
  • 2016-10-16
  • 2014-05-13
  • 2021-06-13
相关资源
最近更新 更多