분명히 64 비트 Linux의 GCC 환경에서 명령 줄 매개 변수를 가져 오려면 Linux 호출 규칙 "System V AMD64 ABI"을 따르는 GCC 호출 규칙에 따라 전달됩니다.
는 이제 C로 프로그램 로직을 번역하자
#include <stdio.h>
int main (int argc, char** argv)
{
if (argc != 0)
{
do
{
puts (*argv);
argc--;
argv++;
} while (argc);
}
return;
}
ASM은 프로그램이 종료 코드를 반환하지 않습니다. 이 종료 코드는 함수가 반환 될 때 RAX
에 있어야합니다. 처음에는 argv
문자열에 프로그램 이름이 들어 있기 때문에 BTW : argc
은 항상> 0입니다.
main
함수는 "호출자"(호출자 : puts
)와 "호출 수신자"(GCC 환경으로 돌아갑니다)입니다. 호출자는 puts
으로 전화하기 전에 RAX
과 RSI
을 보존하고 필요할 때 복원해야합니다. 호출 수신자 저장 레지스터는 사용되지 않습니다. 이 작품 (16)
하여 스택을 정렬하는 것을 잊지 마세요 :
extern puts
global main
section .text
main: ; RDI: argc, RSI: argv, stack is unaligned by 8
mov rax, rdi
label:
test rax, rax
je exit
push rbx ; Push 8 bytes to align the stack before the call
push rax ; Save it (caller-saved)
push rsi ; Save it (caller-saved)
mov rdi, [rsi] ; Argument for puts
call puts
pop rsi ; Restore it
pop rax ; Restore it
pop rbx ; "Unalign" the stack
dec rax
add rsi, 8
jmp label
exit:
; pop rsi ; Once too much
xor eax, eax ; RAX = 0 (return 0)
ret ; RAX: return value