我对汇编语言很陌生,但是对c有一点了解。我正在玩外部函数调用,如
extern _printf
str db "Hello", 0
push str
call _printf
但是找不到使用外部函数的任何教程,除了scanf和printf。例如strcmp?我该如何呼叫strcmp?
答案 0 :(得分:3)
这是我的答案。但是它特定于x86-64。请注意,将参数推入函数时,通常将前6个寄存器分别放置在寄存器rdi
,rsi
,rdx
,rcx
,r8
和{ {1}}。其余的被推入堆栈。此规范称为System V ABI(请注意,Windows使用另一种约定,称为“ Microsoft x64调用约定”)。
r9
答案 1 :(得分:1)
编辑:我在这里犯了一些错误,有关详细信息,请参见评论!
这是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