Sto provando a definire alcune subroutine che hanno chiamate a printf in esse. Un esempio molto banale è il seguente:vengono richiamate due volte senza nemmeno essere chiamate dal principale
extern printf
LINUX equ 80H
EXIT equ 60
section .data
intfmt: db "%ld", 10, 0
segment .text
global main
main:
call os_return ; return to operating system
os_return:
mov rax, EXIT ; Linux system call 60 i.e. exit()
mov rdi, 0 ; Error code 0 i.e. no errors
int LINUX ; Interrupt Linux kernel
test:
push rdi
push rsi
mov rsi, 10
mov rdi, intfmt
xor rax, rax
call printf
pop rdi
pop rsi
ret
Qui test ha solo una chiamata a printf che emette il numero 10 allo schermo. Non mi aspetterei che venga chiamato perché non ho nessuna chiamata.
Tuttavia durante la compilazione e l'esecuzione:
nasm -f elf64 test.asm
gcc -m64 -o test test.o
ottengo l'output:
10
10
Sono totalmente sconcertato e mi chiedevo se qualcuno potrebbe spiegare perché questo sta accadendo?
Grazie! Metto il valore 60 (EXIT) in rdi allora invece di rax, come chiamare printf? –
No, inserendo il numero di syscall in 'rax' e il primo argomento in' rdi' è corretto. Si veda http://www.x86-64.org/documentation/abi.pdf (appendice A in particolare) per la documentazione dell'ABI del kernel syscall e le differenze dalle convenzioni di chiamata a livello utente. –
Mi spiace continuare a tormentarti su questo, ma ho cambiato la riga "int LINUX" per chiamare syscall e aggiunto extern syscall verso l'alto e ottenere ancora i due dieci. C'è qualche possibilità che tu possa mostrarmi un mini esempio di come chiamare syscall? Grazie mille :) –