Hoe alloceren functies zoals alloca geheugen van de stack?

Een tijdje geleden besprak ik hoe compilers ervoor zorgen dat grote stack-allocaties niet over de guard page heen springen. Shawn Van Ness was benieuwd hoe dit werkt met alloca. "Voert het de nodige chkstk()-probing uit?"

Ja, de alloca()-functie roept dezelfde chkstk()-functie aan om de stack te controleren (proben) voordat de stack-pointer wordt aangepast voor het gealloceerde geheugen.

Hier is een kunstmatig voorbeeld:

#include <malloc.h>
void consume(void*,void*);

void f(int n)
{
    char buffer[16384];
    consume(alloca(n), buffer);
}

Op x86-64 resulteert dit in:

push    rbp
mov     eax, 16416          ; probe for local frame
call    __chkstk
sub     rsp, rax            ; create local frame
lea     rbp, [rsp+32]
movsxd  rax, ecx            ; n
lea     rcx, [rax+15]       ; round up to multiple of 16
and     rcx, -16
mov     rax, rcx            ; special __chkstk calling convention
call    __chkstk
sub     rsp, rcx            ; allocate n bytes
lea     rdx, [rbp]          ; rdx -> buffer
lea     rcx, [rsp+32]       ; rcx -> alloca'd memory
call    consume
lea     rsp, [rbp+16384]    ; clean up local frame
pop     rbp
ret     0

Merk op dat dezelfde __chkstk-functie wordt gebruikt, zowel voor het uitvoeren van de initiële stack-probe bij het maken van het lokale frame als voor de alloca().