[英]X86-64 NASM calling extern c functions
我对汇编很陌生,但知道一点 C。我在玩像 extern 函数调用
extern _printf
str db "Hello", 0
push str
call _printf
但除了scanf
和printf
之外,找不到任何使用 extern 函数的教程。 我如何调用strcmp
?
这是我的答案。 不过,它特定于 x86-64。 请注意,在向函数推送参数时,您通常将前 6 个放在寄存器rdi
、 rsi
、 rdx
、 rcx
、 r8
和r9
。 其余的被压入堆栈。 此规范称为 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.