Если вы удалите printf();
вызов, вы получите это:
.LC0:
.string "test.txt"
main:
push rbp
mov rbp, rsp
sub rsp, 56
.LBB2: // m_lstats
mov QWORD PTR [rbp-8], 6 // _rax = 6;
mov QWORD PTR [rbp-16], OFFSET FLAT:.LC0 // _path = PATH;
lea rax, [rbp-176] // _fs = FS;
mov QWORD PTR [rbp-24], rax
mov rax, QWORD PTR [rbp-8] // %rax = _rax
mov rdx, QWORD PTR [rbp-16] // %rdx = _path
mov rsi, QWORD PTR [rbp-24] // %rsi = _fs
mov rdi, rdx // %rdi = _path
syscall // call
mov DWORD PTR [rbp-28], eax // ret = %eax (low %rax)
.LBE2: // back to main
mov eax, 0 // return 0; // @ main()
leave
ret
, все остальное - просто подготовка к printf();
(назад к printf)
.LC0:
.string "test.txt"
.LC1:
.string "ret %d\n"
(...)
syscall // call
mov DWORD PTR [rbp-28], eax // (*)ret = %eax (low %rax)
mov eax, DWORD PTR [rbp-28] // %esi = &ret
mov esi, eax //
mov edi, OFFSET FLAT:.LC1 // %edi = &"ret %d\n"
mov eax, 0 // %eax = 0 // ?
call printf
Итак, вы получите возвращаемое значение в ret
(mov DWORD PTR [rbp-28], eax
), и, как вы сказали, возвращаемое значение находится в %rax
. Следовательно, вы должны иметь возможность доступа к ret
, как к любой нормальной переменной.
PS. Надеюсь, вы не возражаете против синтаксиса Intel, смешанного с %reg
,% означает регистр в противоположность переменной. Я знаю, что не будет переменной rax
, но чтобы сделать ее более читабельной, я использовал это украшение.