其它語言引入Nasm自定義函數
C/C++可以使用 extern 來引用外部函數,在link時必須包含該庫
Python用ctype.CDLL()載入已經做成.so/.dll的動態鏈結函式庫
遵循著函數參數順序和本篇底下的暫存器保存規範
以下是一個Nasm找n個數字最大值的例子,int64_t max_n(n, n1, n2, ...)
global max_n
section .text
max_n: dec rdi jz end cmp rsi, rdx cmovl rsi, rdx ; 上面cmp小於則mov dec rdi jz end cmp rsi, rcx cmovl rsi, rcx dec rdi jz end cmp rsi, r8 cmovl rsi, r8 dec rdi jz end cmp rsi, r9 cmovl rsi, r9 dec rdi jz end mov rcx, 1
loop: inc rcx cmp rsi, [rsp+rcx*8] cmovl rsi, [rsp+rcx*8] dec rdi jnz loop
end: mov rax, rsi ret然後在C語言引用max_n函數
#include <stdio.h>#include <inttypes.h>
extern int64_t max_n(int64_t, ...);
int main() { printf("%ld\n", max_n(10, 130, 2, 1, 5, 6, 95, 600, 105, 120, 100)); return 0;}組譯nasm <- 並用gcc編譯鏈結C代碼和這個
nasm -f elf64 file.asm -o file.o && gcc call_nasm.c file.o -o call_nasm./call_nasmCaller/Callee saved
Section titled “Caller/Callee saved”需要注意的是根據ABI規範暫存器分為呼叫者保存(Caller-saved)和被呼叫者保存( Callee-saved)
Caller-saved
Section titled “Caller-saved”使用call回來後以下暫存器的內容是可能被改變的
rax, rcx, rdx, rsi, rdi, r8, r9, r10, r11, rflags
Callee-saved
Section titled “Callee-saved”被call進入後的函數應該保存以下暫存器的值不能破壞
rbx, rbp, rsp, r12, r13, r14, r15
如果要使用這幾個暫存器一般在開頭push最後結尾pop還原,像是這樣
func: push rbx push rbp ; ...... pop rbp pop rbx ret