【问题标题】:Segfault moving (%eax), %ebx on the second iteration of this loop?在此循环的第二次迭代中,Segfault 移动 (%eax)、%ebx?
【发布时间】:2021-08-04 20:27:35
【问题描述】:

我是汇编新手,正在尝试一次打印一个字符串的一个字符,目前为止。

    .equ  STDOUT,1
    .equ  WRITE,4
    .equ  EXIT,1

char_string:
    .asciz "hello, world"
    
.text
    .globl _start

_start:
    movl $char_string, %eax
    call print_str
    movl $EXIT, %eax
    int $0X80
    
print_str:
        mov (%eax), %ebx
        movl $WRITE, %eax
        movl $STDOUT, %ebx
        movl $char_string, %ecx
        movl $1, %edx
        int $0x80
        inc %eax
        cmpl $0, %ebx
        jne print_str
        je out_of_loop
out_of_loop:
    ret

但是,当我尝试编译时,我在该行遇到了分段错误 move (%eax), %ebx 这有什么问题?我该如何解决?我试图将字符串的指向字符移动到 %ebx 以进行打印,然后我增加 eax 以移动到字符串中的下一个字符。

【问题讨论】:

  • write 系统调用需要一个指针。所以mov (%eax), %ebx 第一次就错了,它只是没有崩溃。 eax 被用作返回值,所以这就是为什么它会被破坏并导致第二次崩溃。
  • 所以我应该使用 [eax] 而不是 (%eax) 吗?
  • 啊,我明白你想做什么了。 [eax] 是 intel 语法,你不能使用它,你还是会覆盖 ebx

标签: assembly x86 att


【解决方案1】:

崩溃的直接原因是eax被用作系统调用的返回值。但是,您的代码在其他方面也是错误的。我已经评论了你的代码:

print_str:
        mov (%eax), %ebx           # loads 4 bytes not 1
        movl $WRITE, %eax
        movl $STDOUT, %ebx         # overwrites ebx you loaded
        movl $char_string, %ecx    # uses the starting address instead of iterating
        movl $1, %edx
        int $0x80
        inc %eax                   # eax is return value of system call by now
        cmpl $0, %ebx              # ebx is $STDOUT, see above
        jne print_str
        je out_of_loop             # makes no sense to jump to next instruction
out_of_loop:
    ret

一个可能的解决方案是:

print_str:
        mov %eax, %ecx             # address of char to print
        movl $STDOUT, %ebx
        movl $1, %edx
print_str_loop:
        cmpb $0, (%ecx)            # test for terminating zero byte
        je out_of_loop
        movl $WRITE, %eax          # reload eax as it is return value from a previous iteration
        int $0x80
        inc %ecx                   # point to next character
        jmp print_str_loop
out_of_loop:
        ret

【讨论】:

  • 在循环的第一行使用 cmpb 是否有原因? cmpb 是在比较字节吗?
  • 是的。终止的零只是 1 个字节。 .asciz 字符串中的所有字符均为 1 个字节。
猜你喜欢
  • 1970-01-01
  • 2016-10-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-07-02
  • 1970-01-01
  • 2010-12-28
  • 1970-01-01
相关资源
最近更新 更多