이 대답은 나를 당혹스럽게했다.
에 따르면 표준 C 호출 규칙 , C 함수를 호출 할 수있는 표준 방법이다 push
스택과 인수 call
서브 루틴. 이는 적절한 인수로 다른 레지스터를 설정 한 다음 다른 레지스터를 설정하는 syscall 과 분명히 다릅니다 syscall
.
그러나 위에서 언급 한 답변은 다음 GAS 코드를 제공합니다.
.global main
.section .data
hello: .asciz "Hello\n"
.section .text
main:
movq $hello, %rdi
movq $0, %rax
call printf
movq $0, %rax
ret
있는 작품 gcc hello.s -o hello
. 호출하는 부분 printf
은 다음과 같습니다.
movq $hello, %rdi
movq $0, %rax
call printf
rdi
스택이 아닌 레지스터를 사용 하여 인수를에 전달합니다 printf
. 위를 다음으로 변경
push $hello
call printf
분할 오류가 발생합니다.
printf
는 C 함수 이기 때문에 ,와 달리 sys_write
인수는 레지스터가 아니라 스택에 전달되어야한다고 생각합니다. 내가 여기서 무엇을 오해하고 있습니까? 다음과 같은 다른 표준 C 함수는 malloc
어떻습니까?
(어떤 참조라도 진정으로 감사하겠습니다.)
가변 함수에 인수를 전달하는 것은 더 복잡합니다. x86-64 ELF ABI , 섹션 3.5.7을 참조하십시오 . 그렇지 않으면 x86-64는 레지스터를 사용하여 처음 6 개의 인수를 전달합니다 %rdi, %rsi, %rdx, %rcx, %r8, %r9
(부동 / 벡터 인수 제외).
사양에 %rax = 0
따르면 가변 인수 목록에 벡터 레지스터에 전달 된 부동 소수점 인수가 없습니다 (0). 당신의 접근 방식은 첫 번째 인수 (예를 들어, NUL 종료 문자열 :로, 잘못 "Hello\n"
)에 전달해야 %rdi
하고, %rax
함수가 호출 될 때 0이어야합니다.
이 기사는 인터넷에서 수집됩니다. 재 인쇄 할 때 출처를 알려주십시오.
침해가 발생한 경우 연락 주시기 바랍니다[email protected] 삭제
몇 마디 만하겠습니다