0

GNU 어셈블러 용 x64 어셈블리를 작성 중입니다. .seh_ * 지시문에 대해 read을 시도했지만 그 정보가 많지 않습니다. gas 문서에는 전혀 언급되어 있지 않습니다..seh_stackalloc 및 스택 정렬

그러나 이해한다면 SEH unwind 작업 중에 코드가 스택에있을 수 있으므로이 코드를 사용해야합니다. 그리고 내 코드는 조작을 스택하고 다른 함수를 호출하기 때문에 SEH가 가능하므로이 코드를 사용해야합니다.

.seh_proc FCT 
FCT: 

push %rbp 
.seh_pushreg %rbp 

mov %rsp, %rbp 
.seh_setframe %rbp, 0 

push %r14 
.seh_pushreg %r14 

lea -(iOffset + iBytes)(%rsp), %rsp 
.seh_stackalloc iOffset + iBytes 

andq $-16, %rsp <---- But what about this? 

.seh_endprologue 

etc... 

를하지만 확실하지 않다 하나의 비트가있다 :

는 대부분 내가 바로 그것을 가지고 생각합니다. 나는이 지시를 가지고있다 :

나는 어떻게 스택 정렬을 수행하는지 SEH에게 알리는가? 이렇게하면 스택을 15 바이트 (매우 희박한)에서 8 바이트 (매우 가능성 있음)까지 0 바이트 (확실하게 가능)까지 조정할 수 있습니다. 실제 양은 런타임까지 결정될 수 없기 때문에 나는 막혔다.

.seh 명령을 건너 뛸 수 있다고 가정합니다. 그러나 스택의 8 바이트가 거기에 예약되어 있다면, 나는 아마 긴장을 풀었을 것입니다. 그렇지 않습니까? 그게 여기서 모든 목적을 이길 수 있니?

대체로 정렬을 생략 할 수 있습니다. 하지만 다른 함수 (memcpy)를 호출하면 스택을 정렬한다고 생각하지 않습니까? MS에 따르면

스택은 항상 프롤로그이 통해 어쩌면

내가 할 수있는 '이유'내 방식대로 내를 제외하고, 16 바이트로 정렬 유지됩니다? 나에게 전화 한 사람이 일을 올바르게했다면 ... call을 수행했을 때 스택이 정렬되었으므로 이제 내 프롤로그에서 수행 한 작업에 8 바이트 (반송 주소)가 더해집니다. 이것에 의지 할 수 있을까요? 깨지기 쉬운 것 같아.

다른 코드를 살펴 보았지만, 내가보고있는 것을 신뢰할 수 있는지 잘 모르겠습니다. gas에서 .seh_ *을 잘못 사용하여 오류가 발생했다고 의심됩니다. 실제 예외 (그리고 어쩌면 항상 그런 것은 아닐 수도 있습니다) 중에 만 문제를 볼 수 있습니다.

내가 이것을 할 경우, 바로하고 싶습니다. 스택 정렬이 일반적인 것 같아서 누군가가 여기에 해결책을 가져야 만합니다. 나는 단지 그것을 보지 않고있다.

답변

0

gcc가 작성한 코드를 보면 나는 답을 알고 있다고 생각합니다. 내 '이유'접근법을 따라 바른 길을 가고있었습니다.

함수가 호출되면 스택은 (call 때문에) 일시적으로 정렬이되지 않지만 pushq %rbp을 통해 거의 즉시 재정렬됩니다. 그런 다음 스택에 대한 조정 (로컬 변수 또는 호출 된 함수에 대한 매개 변수의 스택 공간 등)은 항상 16의 배수를 사용하여 수행됩니다. 따라서 프롤로그 끝에 스택이 항상 올바르게 다시 정렬되고 그런 식으로 유지됩니다 다음 번까지 call.

즉, andq $-16, %rsp을 사용하여 스택을 정렬 할 수 있지만 내 프롤로그를 올바르게 작성하지 않아도됩니다.

주의 : 잎 기능 (즉, 다른 기능을 호출하지 않는 기능)은 스택을 정렬 할 필요가 없습니다 (https://msdn.microsoft.com/en-us/library/67fa79wz.aspx).