【问题标题】:NASM assembly code working before, but not now and is dropping a segmentation faultNASM 汇编代码以前可以工作,但现在不行,并且正在丢弃分段错误
【发布时间】:2021-05-14 20:24:22
【问题描述】:

edit: I added an image of the error shown in gdb 我的汇编代码有问题。这段代码曾经对我有用,它给出了我需要的正确输出(主要是 string1,因为我需要将它的元音字符更改为其他字符)。然而,几个小时后,它停止工作,现在正在转储分段错误。

section .data
    NULL equ 0
    SYS_EXIT equ 60
    string1 db 'hello everyone', NULL
    strlen dq 0

section .bss
    string2 resb 20

section .text
_start:
    mov rdi, string1
    mov rsi, strlen
    call get_strlen

    mov rdi, qword[strlen]
    mov rsi, string1
    mov rdx, string2
    call get_vowel

exit_here:
    mov rax, SYS_EXIT
    xor rdi, rdi
    syscall


get_strlen:
    len_loop:
        mov al, byte[rdi]
        cmp al, NULL
        je return

        inc rdi
        inc byte[rsi]
        jmp len_loop
    return:
        ret

get_vowel:
    mov rcx, rdi
    mov rsi, rsi
    mov rdi, rdx
    cld
    str_loop:

    lodsb
    stosb

    cmp al, 'a'
    je vowel_a
    cmp al, 'e'
    je vowel_e
    cmp al, 'i'
    je vowel_i
    cmp al, 'o'
    je vowel_o
    cmp al, 'u'
    je vowel_u
    loop str_loop

    mov byte[rdi], NULL
    jmp str_copy

    vowel_a:
        dec rdi
        mov byte[rdi], '@'
        inc rdi
        jmp str_loop

    vowel_e:
        dec rdi
        mov byte[rdi], '3'
        inc rdi
        jmp str_loop

    vowel_i:
        dec rdi
        mov byte[rdi], '1'
        inc rdi
        jmp str_loop

    vowel_o:
        dec rdi
        mov byte[rdi], '0'
        inc rdi
        jmp str_loop

    vowel_u:
        dec rdi
        mov byte[rdi], 'U'
        inc rdi
        jmp str_loop

    str_copy:
        mov rcx, rdi
        mov rsi, rdx
        mov rdi, rsi
        cld
        jmp loop1

        loop1:
           lodsb
           stosb
           loop loop1 
           mov byte[rdi], NULL
           jmp return1
    return1:
     ret

根据 gdb,函数 get_vowel 的 on loop1 存在问题。但是,根据我目前对组装的了解,我相当确定它是有效的。

在这种情况下 string1 的假定值为

h3ll0 3v3ry0n3

但是它只输出它的默认值

【问题讨论】:

  • 补充一点,在这一切发生之前,我的电脑突然变得不稳定而且非常慢,所以我重新启动它,它也带有一个错误代码,据说与我的内存有关。不确定这与它有什么关系,但我不妨把它放在那里。
  • 可能与问题无关,但您忘记在定义_start 之前输入global _start,因此链接器找不到它,可能会默认使用其他地址进行输入。
  • 是的,我在帖子中省略了使函数全局化的部分
  • loop str_loop rcx 之后为零。然后你做一个jmp str_copy 最终以loop loop1 结束,然后尝试重复 2^64 次。这是一种可能的故障模式,可能还有其他的。在 gdb 中使用单步。
  • 是的。您有jmp str_copy,但str_copymov rcx, rdi 开头,但rdi 已设置为mov rdi, rdx 的地址。

标签: assembly nasm


【解决方案1】:

原来代码一开始并没有真正工作,哈哈。 str_copy 循环中的 rcx 的值是一个地址,rdirsi 的值没有被切换,所以如果有的话,代码的那部分没有发生任何事情。为了解决这个问题,我初始化了另一个具有相同值rcx 的寄存器和另一个交换rdirsi 地址的函数,因此我可以将string2 的内容复制到string1,如函数所示下面

swap:
push rbp
mov rbp, rsp
sub rsp, 8

mov r10, rdi
mov qword[rbp-8], r10
mov r10, rsi
mov rdi, r10
mov r10, qword[rbp-8]
mov rsi, r10
jmp swap1

swap1:
mov rcx, rdx
mov rsi, rsi
mov rdi, rdi
cld

loop1:
    movsb
    loop loop1
    mov byte[rdi], NULL

add rsp, 8
pop rbp
ret

【讨论】:

    猜你喜欢
    • 2014-11-15
    • 2012-05-09
    • 1970-01-01
    • 2015-03-31
    • 2021-03-22
    • 1970-01-01
    • 2019-02-03
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多