은 내가 나에게 관심 뭔가를 발견했습니다 좋고 나는 그것에 대한 답을 찾기 위해 관리하지 않았다? i386에서 호출 규칙은 스택에 매개 변수를 전달하므로 매크로는 스택 기본을 가리키는 포인터를 증가시키고 을 전달하지만 x64에서는 모든 매개 변수가 레지스터로 전달됩니다 .... 그래서 어떻게됩니까? 호출 된 함수는 인수를 전달하는 데 사용 된 레지스터를 어떻게 알 수 있습니까?가변 가지 인자 및 x64
답변
이것은 아키텍처의 ABI에서 정의합니다.
변수 인수 목록을 복용하고 알려진 함수의 프롤로그 매크로 va_start를가 전화 : AMD64에 대한 시스템 V ABI (윈도우 이외 그래서 거의 모든)에서 ABI document는 (앞으로 페이지 56) 말한다 인수 레지스터를 레지스터 저장 영역에 저장해야합니다.
그런 다음 va_list
(모든 함수 인수가 레지스터에 맞지 않는) 영역 저장 레지스터에 대한 포인터와 몇 가지 추가 인수가 전달 될 수 있었다 스택에 장소 구조체이다.
이것은 컴파일러 지원이 필요하며 모든 가변 함수는 모든 레지스터를 스택에 저장해야한다는 것을 의미합니까? – DrPrItay
@DrPrItay : ABI는 어떤 레지스터를 사용할 수 있는지 지정합니다. 16 개 정수 레지스터 중 6 개만이 arg-passing (SysV 호출 규칙)에서 사용되는 반면 다른 레지스터는 항상 함수 호출에 의해 제약을받을 수 있습니다. –
일부 (많은?) 컴파일러는 _might_ 인수를 x64 모드에서 레지스터로 전달하지만 이는 고유 한 x86 대 x64 차이가 아니며 선택 사항입니다. 또한 항상 레지스터에 _all_ 인수를 전달할 수있는 것은 아닙니다 (100 개의 매개 변수가있는 함수?). 'va_list'는 얼마나 많은 인자가 레지스터에 전달되었는지, 어느 레지스터에 전달되었는지에 대한 세부 사항을 담을 수 있지만, _ _ _ _는 모든 경우에 가변 인자가 단순히 스택에 전달된다는 것입니다. – TripeHound
[이 블로그 게시물] (https://blog.nelhage.com/2010/10/amd64-and-va_arg/)은 그것을 설명합니다 – samgak
@TripeHound 그것은 컴파일러가 아닙니다. 사람들은 왜이 신화를 믿고 그것을 전파합니까? 컴파일러는 원하는 모든 것을 할 수 있지만 컴파일러는 쓸모가 없습니다. 컴파일러는 ABI가 잘 정의 된 아키텍처를 대상으로합니다. 그리고 현재 존재하는 x64 ABI는 둘 다 함수 인수를 전달하기위한 레지스터를 지정합니다. variadic 함수 (그 함수와 일반 함수 사이에는 차이가 없음)에 대해서조차. – Art