1PROC_FRAME sample
2   db      048h; emit a REX prefix, to enable hot-patching
3push rbp
4[pushreg rbp]
5sub rsp, 040h
6[allocstack 040h]
7lea rbp, [rsp+020h]
8[setframe rbp, 020h]
9movdqa [rbp], xmm7
10[savexmm128 xmm7, 020h];the offset is from the base of the frame
11;not the scaled offset of the frame
12mov [rbp+018h], rsi
13[savereg rsi, 018h]
14mov [rsp+010h], rdi
15[savereg rdi, 010h]; you can still use RSP as the base of the frame
16; or any other register you choose
17END_PROLOGUE
18
19; you can modify the stack pointer outside of the prologue (similar to alloca)
20; because we have a frame pointer.
21; if we didn't have a frame pointer, this would be illegal
22; if we didn't make this modification,
23; there would be no need for a frame pointer
24
25sub rsp, 060h
26
27; we can unwind from the following AV because of the frame pointer
28
29mov rax, 0
30mov rax, [rax] ; AV!
31
32; restore the registers that weren't saved with a push
33; this isn't part of the official epilog, as described in section 2.5
34
35movdqa xmm7, [rbp]
36mov rsi, [rbp+018h]
37mov rdi, [rbp-010h]
38
39; Here's the official epilog
40
41lea rsp, [rbp-020h]
42pop rbp
43ret
44ENDPROC_FRAME
45struc kFrame
46.Fill     resq 1	; fill to 8 mod 16 
47.SavedRdi resq 1	; saved register RDI 
48.SavedRsi resq 1	; saved register RSI 
49endstruc
50
51struc sampleFrame
52.Fill     resq 1	; fill to 8 mod 16
53.SavedRdi resq 1	; Saved Register RDI 
54.SavedRsi resq 1	; Saved Register RSI
55endstruc
56
57PROC_FRAME sample2
58alloc_stack sampleFrame_size
59save_reg rdi, sampleFrame.SavedRdi
60save_reg rsi, sampleFrame.SavedRsi
61END_PROLOGUE
62
63; function body
64
65mov rsi, [rsp+sampleFrame.SavedRsi]
66mov rdi, [rsp+sampleFrame.SavedRdi]
67
68; Here's the official epilog
69
70add rsp, sampleFrame_size
71ret
72ENDPROC_FRAME
73
74