繁体   English   中英

X86-64 NASM 调用 extern c 函数

[英]X86-64 NASM calling extern c functions

我对汇编很陌生,但知道一点 C。我在玩像 extern 函数调用

extern _printf
str db "Hello", 0
push str
call _printf

但除了scanfprintf之外,找不到任何使用 extern 函数的教程。 我如何调用strcmp

这是我的答案。 不过,它特定于 x86-64。 请注意,在向函数推送参数时,您通常将前 6 个放在寄存器rdirsirdxrcxr8r9 其余的被压入堆栈。 此规范称为 System V ABI(请注意,Windows 使用一种不同的约定,称为“Microsoft x64 调用约定”)。

    segment .data     ; or use .rodata for read-only data.
str1    db      "Hello", 0x0
str2    db      "Hellx", 0x0
fmt     db      "Comparison = %d", 0xa, 0x0

segment .text
    global main
    extern strcmp, printf
    default rel             ; RIP-relative addressing for [name] is what you want.

main:
    ; Create a stack-frame, re-aligning the stack to 16-byte alignment before calls
    push rbp
    mov rbp, rsp

    ; Prepare the arguments for strcmp.
    lea rdi, [str1]
    lea rsi, [str2]

    ; Call strcmp, return value is in rax.
    call strcmp

    ; Prepare arguments for printf.
    lea rdi, [fmt]
    mov esi, eax  ; int return value from strcmp -> 2nd arg for printf
    xor eax, eax  ; Indicate no floating point args to printf.

    ; Call printf
    call printf

    ; Return 0 (EXIT_SUCCESS), and destroy the stack frame.
    xor eax, eax
    leave            ; or just pop rbp because RSP is still pointing at the saved RBP
    ret

编辑:我在这里犯了一些错误,详情见评论!

这是一个 32 位版本(低于 64 位):

SECTION .data
    ; global functions in this file
    global main

    ; extern functions
    extern strcmp

hworld: ; our first string
    db "hello world", 0

hworld2: ; our second string
    db "hello world2", 0

SECTION .text

;=============================================================================
; The program entrypoint
;
main:

    ; int rv = strcmp("hello world", "hello world2");
    push    hworld2
    push    hworld
    call    strcmp

    ; _exit(rv);
    mov     ebx, eax
    mov     eax, 1
    int     0x80

然后你可以编译它:

nasm -f elf main.s -o main.o
cc -m32 main.o -o hello_world

这是 64 位版本:

SECTION .data
    ; global functions in this file
    global main

    ; extern functions
    extern strcmp

hworld: ; our first string
    db "hello world", 0

hworld2: ; our second string
    db "hello world2", 0

SECTION .text

;=============================================================================
; The program entrypoint
;
main:

    ; int rv = strcmp("hello world", "hello world2");
    mov     rsi, hworld2
    mov     rdi, hworld
    call    strcmp

    ; _exit(rv);
    mov     rdi, rax
    mov     rax, 60
    syscall

然后你可以编译 x64 版本:

nasm -f elf64 main.s -o main.o
cc main.o -o hello_world

并运行它:

$ ./hello_world 
$ echo $?
206

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM