x86-64 程序集:GCC 出现分段错误,但 ld [重复] 不会出现分段错误

问题描述 投票:0回答:0

我正在使用 nasm 进行 x86-64 汇编。我的任务是编写一个代码,接受一个数字作为命令行参数并将其转换为整数。使用 ld 链接器链接时,代码正常工作。但是如果使用 GCC 链接器,就会出现段错误。

这是我写的代码:

Projekat.asm:

    %include "Macros.asm"

    section .data

    section .bss
    
    section .text
    global main
    main:
        mov rax, [rsp + 16]      ; This line is used to store the second argument (which is the number) 
                             ; into rax register
        call _convertToInt
        newline                  ; newline, exit and rax are macros located in Macros.asm
        exit 

    _convertToInt: 
        mov rdi, rax

        mov rax, 0
        _convertLoop: 
            movzx rcx, byte [rdi]   ; By using GDB, I found out that Segfault occurs on this line!
            cmp rcx, 0
            je _end
            sub rcx, 48
            imul rax, 10
            add rax, rcx
            inc rdi 
            jmp _convertLoop

        _end: 
            printValue rax      
            ret

宏.asm:

    section .data
        newline db 10, 0
        newline_length equ $-newline 

    section .bss
        digitSpace resb 100
        digitSpacePos resb 8




    %macro newline 0
        mov rax, 1
        mov rdi, 1
        mov rsi, newline 
        mov rdx, 1 
        syscall
    %endmacro

    %macro exit 0
        mov rax, 60
        mov rdi, 0
        syscall
    %endmacro

    %macro printValue 1
        mov rax, %1

        mov rcx, digitSpace
        mov [digitSpacePos], rcx 

    %%printValLoop:
        mov rdx, 0 
        mov rbx, 10
        div rbx   
        mov r14, rax  
        add rdx, 48  

        mov rcx, [digitSpacePos]
        mov [rcx], dl  
        inc rcx 
        mov [digitSpacePos], rcx

        mov rax, r14 
        cmp rax, 0
        jne %%printValLoop

    %%printValFinalLoop:
        mov rcx, [digitSpacePos]

        mov rax, 1
        mov rdi, 1
        mov rsi, rcx
        mov rdx, 1
        syscall

        mov rcx, [digitSpacePos]
        dec rcx
        mov [digitSpacePos], rcx

        cmp rcx, digitSpace
        jge %%printValFinalLoop
    %endmacro

我正在使用 64 位 Ubuntu 20.04。以下是我使用的命令:

nasm -f elf64 -g -F dwarf Projekat.asm
ld -o Projekat Projekat.o
./Projekat 485

;在这种情况下,代码正常运行并打印数字!

但是,如果我使用 GCC 作为链接器,会发生这种情况:

nasm -f elf64 -g -F dwarf Projekat.asm
gcc Projekat.o -static -o Projekat
./Projekat 485

;导致段错误

我还使用了 backtrace 命令,这就是堆栈的样子:

#0  _convertLoop () at Projekat.asm:59
#1  0x0000000000401c0a in main () at Projekat.asm:13

我已经尝试解决这个问题 7 天了,如果有人知道段错误背后的问题是什么以及为什么代码在 ld 而不是 GCC 下正常工作,请告诉我。 提前感谢大家!

编辑:将 main 更改为 _start 可使代码与 ld 链接一起正常工作。但是,通过将 _start 更改为 main 并使用 gcc,代码不再有效。

assembly gcc segmentation-fault x86-64 ld
© www.soinside.com 2019 - 2024. All rights reserved.