से भी बुलाए बिना दो बार बुलाया जाता है, मैं उन कुछ subroutines को परिभाषित करने की कोशिश कर रहा हूं जिनके पास printf को कॉल किया गया है। एक बहुत ही तुच्छ उदाहरण इस प्रकार है:असेंबली सबराउटिन को मुख्य
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
यहाँ परीक्षण सिर्फ printf कि स्क्रीन पर नंबर 10 आउटपुट के लिए एक कॉल है। मैं इसे कॉल करने की उम्मीद नहीं करता क्योंकि मुझे इसके लिए कोई फोन नहीं है।
हालांकि संकलन है और चल रहा है जब:
nasm -f elf64 test.asm
gcc -m64 -o test test.o
मैं आउटपुट प्राप्त:
10
10
मैं पूरी तरह विस्मित कर रहा हूँ और सोचा कि अगर किसी को समझा सकता है क्यों यह हो रहा है?
धन्यवाद:
64-बिट सिस्टम कॉल के लिए, बजाय
syscall
अनुदेश का उपयोग करें! क्या मैं मूल्य 60 (EXIT) आरडीआई में डालता हूं, फिर रैक्स के बजाय, printf को कॉल करने के समान? –नहीं, 'रैक्स' में syscall संख्या डालना और 'rdi' में पहला तर्क सही है। कर्नेल syscall एबीआई के कुछ दस्तावेज और उपयोगकर्ता स्तर के कॉलिंग सम्मेलनों के अंतर के लिए http://www.x86-64.org/documentation/abi.pdf (विशेष रूप से परिशिष्ट ए) देखें। –
इस बारे में आपको बुरा रखने के लिए खेद है, लेकिन मैंने syscall को कॉल करने के लिए "int LINUX" पंक्ति को बदल दिया और शीर्ष पर बाहरी सिस्कोल जोड़ा और अभी भी दो दस प्राप्त करें। क्या कोई मौका है कि आप मुझे सिस्कोल को कॉल करने का एक छोटा सा उदाहरण दिखा सकते हैं? बहुत बहुत धन्यवाद :) –