-mpreferred-stack-boundary
#!/usr/bin/env bash
set -ex
start_string=++++++++++++++++
end_string=-----------------
echo > result32.txt
echo > result64.txt
for BIT_SIZE in 32 64
do
for VAR in "default" {2..12}
do
OPTION="-mpreferred-stack-boundary=$VAR"
if [ "default" = "$VAR" ]; then
OPTION=""
fi
if [[ "$VAR" -eq 2 && "$BIT_SIZE" -eq 64 ]]; then
continue
fi
filename="flag$BIT_SIZE""_""$VAR"
gcc main.c -o $filename -m$BIT_SIZE $OPTION -Wno-format-security
echo $start_string >> result$BIT_SIZE.txt
echo option: $VAR >> result$BIT_SIZE.txt
gdb -batch -ex 'x/10i main' $filename >> result$BIT_SIZE.txt
echo $end_String >> result$BIT_SIZE.txt
rm $filename
done
done
- -mpreferred-stack-boundary=N 옵션
main 을 포함하여 이후에 불리는 모든 함수들의
스택프레임에서 가장 낮은 주소
가 2^N 에 배수가 되도록 align 을 해줌result32.txt
++++++++++++++++ option: default [31m[1mpwndbg: [0m[31m[0m[91mloaded 193 commands. Type [35mpwndbg [filter][0m[91m for a list.[0m [31m[1mpwndbg: [0m[31m[0m[91mcreated [35m$rebase[0m[91m, [35m$ida[0m[91m gdb functions (can be used with print/break)[0m 0x1335 <main>: endbr32 0x1339 <main+4>: lea ecx,[esp+0x4] 0x133d <main+8>: and esp,0xfffffff0 0x1340 <main+11>: push DWORD PTR [ecx-0x4] 0x1343 <main+14>: push ebp 0x1344 <main+15>: mov ebp,esp 0x1346 <main+17>: push esi 0x1347 <main+18>: push ebx 0x1348 <main+19>: push ecx 0x1349 <main+20>: sub esp,0x8c ++++++++++++++++ option: 2 [31m[1mpwndbg: [0m[31m[0m[91mloaded 193 commands. Type [35mpwndbg [filter][0m[91m for a list.[0m [31m[1mpwndbg: [0m[31m[0m[91mcreated [35m$rebase[0m[91m, [35m$ida[0m[91m gdb functions (can be used with print/break)[0m 0x132f <main>: endbr32 0x1333 <main+4>: push ebp 0x1334 <main+5>: mov ebp,esp 0x1336 <main+7>: push esi 0x1337 <main+8>: push ebx 0x1338 <main+9>: sub esp,0x70 0x133b <main+12>: call 0x11d0 <__x86.get_pc_thunk.bx> 0x1340 <main+17>: add ebx,0x2c70 0x1346 <main+23>: mov eax,DWORD PTR [ebp+0xc] 0x1349 <main+26>: mov DWORD PTR [ebp-0x78],eax ++++++++++++++++ option: 3 [31m[1mpwndbg: [0m[31m[0m[91mloaded 193 commands. Type [35mpwndbg [filter][0m[91m for a list.[0m [31m[1mpwndbg: [0m[31m[0m[91mcreated [35m$rebase[0m[91m, [35m$ida[0m[91m gdb functions (can be used with print/break)[0m 0x1332 <main>: endbr32 0x1336 <main+4>: lea ecx,[esp+0x4] 0x133a <main+8>: and esp,0xfffffff8 0x133d <main+11>: push DWORD PTR [ecx-0x4] 0x1340 <main+14>: push ebp 0x1341 <main+15>: mov ebp,esp 0x1343 <main+17>: push esi 0x1344 <main+18>: push ebx 0x1345 <main+19>: push ecx 0x1346 <main+20>: sub esp,0x7c ++++++++++++++++ option: 4 [31m[1mpwndbg: [0m[31m[0m[91mloaded 193 commands. Type [35mpwndbg [filter][0m[91m for a list.[0m [31m[1mpwndbg: [0m[31m[0m[91mcreated [35m$rebase[0m[91m, [35m$ida[0m[91m gdb functions (can be used with print/break)[0m 0x1335 <main>: endbr32 0x1339 <main+4>: lea ecx,[esp+0x4] 0x133d <main+8>: and esp,0xfffffff0 0x1340 <main+11>: push DWORD PTR [ecx-0x4] 0x1343 <main+14>: push ebp 0x1344 <main+15>: mov ebp,esp 0x1346 <main+17>: push esi 0x1347 <main+18>: push ebx 0x1348 <main+19>: push ecx 0x1349 <main+20>: sub esp,0x8c ++++++++++++++++ option: 5 [31m[1mpwndbg: [0m[31m[0m[91mloaded 193 commands. Type [35mpwndbg [filter][0m[91m for a list.[0m [31m[1mpwndbg: [0m[31m[0m[91mcreated [35m$rebase[0m[91m, [35m$ida[0m[91m gdb functions (can be used with print/break)[0m 0x133e <main>: endbr32 0x1342 <main+4>: lea ecx,[esp+0x4] 0x1346 <main+8>: and esp,0xffffffe0 0x1349 <main+11>: push DWORD PTR [ecx-0x4] 0x134c <main+14>: push ebp 0x134d <main+15>: mov ebp,esp 0x134f <main+17>: push esi 0x1350 <main+18>: push ebx 0x1351 <main+19>: push ecx 0x1352 <main+20>: sub esp,0xac ++++++++++++++++ option: 6 [31m[1mpwndbg: [0m[31m[0m[91mloaded 193 commands. Type [35mpwndbg [filter][0m[91m for a list.[0m [31m[1mpwndbg: [0m[31m[0m[91mcreated [35m$rebase[0m[91m, [35m$ida[0m[91m gdb functions (can be used with print/break)[0m 0x1344 <main>: endbr32 0x1348 <main+4>: lea ecx,[esp+0x4] 0x134c <main+8>: and esp,0xffffffc0 0x134f <main+11>: push DWORD PTR [ecx-0x4] 0x1352 <main+14>: push ebp 0x1353 <main+15>: mov ebp,esp 0x1355 <main+17>: push esi 0x1356 <main+18>: push ebx 0x1357 <main+19>: push ecx 0x1358 <main+20>: sub esp,0xec ++++++++++++++++ option: 7 [31m[1mpwndbg: [0m[31m[0m[91mloaded 193 commands. Type [35mpwndbg [filter][0m[91m for a list.[0m [31m[1mpwndbg: [0m[31m[0m[91mcreated [35m$rebase[0m[91m, [35m$ida[0m[91m gdb functions (can be used with print/break)[0m 0x1344 <main>: endbr32 0x1348 <main+4>: lea ecx,[esp+0x4] 0x134c <main+8>: and esp,0xffffff80 0x134f <main+11>: push DWORD PTR [ecx-0x4] 0x1352 <main+14>: push ebp 0x1353 <main+15>: mov ebp,esp 0x1355 <main+17>: push esi 0x1356 <main+18>: push ebx 0x1357 <main+19>: push ecx 0x1358 <main+20>: sub esp,0x16c ++++++++++++++++ option: 8 [31m[1mpwndbg: [0m[31m[0m[91mloaded 193 commands. Type [35mpwndbg [filter][0m[91m for a list.[0m [31m[1mpwndbg: [0m[31m[0m[91mcreated [35m$rebase[0m[91m, [35m$ida[0m[91m gdb functions (can be used with print/break)[0m 0x1356 <main>: endbr32 0x135a <main+4>: lea ecx,[esp+0x4] 0x135e <main+8>: and esp,0xffffff00 0x1364 <main+14>: push DWORD PTR [ecx-0x4] 0x1367 <main+17>: push ebp 0x1368 <main+18>: mov ebp,esp 0x136a <main+20>: push esi 0x136b <main+21>: push ebx 0x136c <main+22>: push ecx 0x136d <main+23>: sub esp,0x2ec ++++++++++++++++ option: 9 [31m[1mpwndbg: [0m[31m[0m[91mloaded 193 commands. Type [35mpwndbg [filter][0m[91m for a list.[0m [31m[1mpwndbg: [0m[31m[0m[91mcreated [35m$rebase[0m[91m, [35m$ida[0m[91m gdb functions (can be used with print/break)[0m 0x1356 <main>: endbr32 0x135a <main+4>: lea ecx,[esp+0x4] 0x135e <main+8>: and esp,0xfffffe00 0x1364 <main+14>: push DWORD PTR [ecx-0x4] 0x1367 <main+17>: push ebp 0x1368 <main+18>: mov ebp,esp 0x136a <main+20>: push esi 0x136b <main+21>: push ebx 0x136c <main+22>: push ecx 0x136d <main+23>: sub esp,0x5ec ++++++++++++++++ option: 10 [31m[1mpwndbg: [0m[31m[0m[91mloaded 193 commands. Type [35mpwndbg [filter][0m[91m for a list.[0m [31m[1mpwndbg: [0m[31m[0m[91mcreated [35m$rebase[0m[91m, [35m$ida[0m[91m gdb functions (can be used with print/break)[0m 0x1356 <main>: endbr32 0x135a <main+4>: lea ecx,[esp+0x4] 0x135e <main+8>: and esp,0xfffffc00 0x1364 <main+14>: push DWORD PTR [ecx-0x4] 0x1367 <main+17>: push ebp 0x1368 <main+18>: mov ebp,esp 0x136a <main+20>: push esi 0x136b <main+21>: push ebx 0x136c <main+22>: push ecx 0x136d <main+23>: sub esp,0xbec ++++++++++++++++ option: 11 [31m[1mpwndbg: [0m[31m[0m[91mloaded 193 commands. Type [35mpwndbg [filter][0m[91m for a list.[0m [31m[1mpwndbg: [0m[31m[0m[91mcreated [35m$rebase[0m[91m, [35m$ida[0m[91m gdb functions (can be used with print/break)[0m 0x1360 <main>: endbr32 0x1364 <main+4>: lea ecx,[esp+0x4] 0x1368 <main+8>: and esp,0xfffff800 0x136e <main+14>: push DWORD PTR [ecx-0x4] 0x1371 <main+17>: push ebp 0x1372 <main+18>: mov ebp,esp 0x1374 <main+20>: push esi 0x1375 <main+21>: push ebx 0x1376 <main+22>: push ecx 0x1377 <main+23>: sub esp,0x1000 ++++++++++++++++ option: 12 [31m[1mpwndbg: [0m[31m[0m[91mloaded 193 commands. Type [35mpwndbg [filter][0m[91m for a list.[0m [31m[1mpwndbg: [0m[31m[0m[91mcreated [35m$rebase[0m[91m, [35m$ida[0m[91m gdb functions (can be used with print/break)[0m 0x136a <main>: endbr32 0x136e <main+4>: lea ecx,[esp+0x4] 0x1372 <main+8>: and esp,0xfffff000 0x1378 <main+14>: push DWORD PTR [ecx-0x4] 0x137b <main+17>: push ebp 0x137c <main+18>: mov ebp,esp 0x137e <main+20>: push esi 0x137f <main+21>: push ebx 0x1380 <main+22>: push ecx 0x1381 <main+23>: sub esp,0x1000
result64.txt
++++++++++++++++ option: default [31m[1mpwndbg: [0m[31m[0m[91mloaded 193 commands. Type [35mpwndbg [filter][0m[91m for a list.[0m [31m[1mpwndbg: [0m[31m[0m[91mcreated [35m$rebase[0m[91m, [35m$ida[0m[91m gdb functions (can be used with print/break)[0m 0x12b4 <main>: endbr64 0x12b8 <main+4>: push rbp 0x12b9 <main+5>: mov rbp,rsp 0x12bc <main+8>: push rbx 0x12bd <main+9>: sub rsp,0x98 0x12c4 <main+16>: mov DWORD PTR [rbp-0x94],edi 0x12ca <main+22>: mov QWORD PTR [rbp-0xa0],rsi 0x12d1 <main+29>: mov rax,QWORD PTR fs:0x28 0x12da <main+38>: mov QWORD PTR [rbp-0x18],rax 0x12de <main+42>: xor eax,eax ++++++++++++++++ option: 3 [31m[1mpwndbg: [0m[31m[0m[91mloaded 193 commands. Type [35mpwndbg [filter][0m[91m for a list.[0m [31m[1mpwndbg: [0m[31m[0m[91mcreated [35m$rebase[0m[91m, [35m$ida[0m[91m gdb functions (can be used with print/break)[0m 0x12b4 <main>: endbr64 0x12b8 <main+4>: push rbp 0x12b9 <main+5>: mov rbp,rsp 0x12bc <main+8>: push rbx 0x12bd <main+9>: sub rsp,0x88 0x12c4 <main+16>: mov DWORD PTR [rbp-0x84],edi 0x12ca <main+22>: mov QWORD PTR [rbp-0x90],rsi 0x12d1 <main+29>: mov rax,QWORD PTR fs:0x28 0x12da <main+38>: mov QWORD PTR [rbp-0x10],rax 0x12de <main+42>: xor eax,eax ++++++++++++++++ option: 4 [31m[1mpwndbg: [0m[31m[0m[91mloaded 193 commands. Type [35mpwndbg [filter][0m[91m for a list.[0m [31m[1mpwndbg: [0m[31m[0m[91mcreated [35m$rebase[0m[91m, [35m$ida[0m[91m gdb functions (can be used with print/break)[0m 0x12b4 <main>: endbr64 0x12b8 <main+4>: push rbp 0x12b9 <main+5>: mov rbp,rsp 0x12bc <main+8>: push rbx 0x12bd <main+9>: sub rsp,0x98 0x12c4 <main+16>: mov DWORD PTR [rbp-0x94],edi 0x12ca <main+22>: mov QWORD PTR [rbp-0xa0],rsi 0x12d1 <main+29>: mov rax,QWORD PTR fs:0x28 0x12da <main+38>: mov QWORD PTR [rbp-0x18],rax 0x12de <main+42>: xor eax,eax ++++++++++++++++ option: 5 [31m[1mpwndbg: [0m[31m[0m[91mloaded 193 commands. Type [35mpwndbg [filter][0m[91m for a list.[0m [31m[1mpwndbg: [0m[31m[0m[91mcreated [35m$rebase[0m[91m, [35m$ida[0m[91m gdb functions (can be used with print/break)[0m 0x12bd <main>: endbr64 0x12c1 <main+4>: push rbp 0x12c2 <main+5>: mov rbp,rsp 0x12c5 <main+8>: push rbx 0x12c6 <main+9>: and rsp,0xffffffffffffffe0 0x12ca <main+13>: sub rsp,0xa0 0x12d1 <main+20>: mov DWORD PTR [rsp+0x1c],edi 0x12d5 <main+24>: mov QWORD PTR [rsp+0x10],rsi 0x12da <main+29>: mov rax,QWORD PTR fs:0x28 0x12e3 <main+38>: mov QWORD PTR [rsp+0x98],rax ++++++++++++++++ option: 6 [31m[1mpwndbg: [0m[31m[0m[91mloaded 193 commands. Type [35mpwndbg [filter][0m[91m for a list.[0m [31m[1mpwndbg: [0m[31m[0m[91mcreated [35m$rebase[0m[91m, [35m$ida[0m[91m gdb functions (can be used with print/break)[0m 0x12c3 <main>: endbr64 0x12c7 <main+4>: push rbp 0x12c8 <main+5>: mov rbp,rsp 0x12cb <main+8>: push rbx 0x12cc <main+9>: and rsp,0xffffffffffffffc0 0x12d0 <main+13>: sub rsp,0xc0 0x12d7 <main+20>: mov DWORD PTR [rsp+0x3c],edi 0x12db <main+24>: mov QWORD PTR [rsp+0x30],rsi 0x12e0 <main+29>: mov rax,QWORD PTR fs:0x28 0x12e9 <main+38>: mov QWORD PTR [rsp+0xb8],rax ++++++++++++++++ option: 7 [31m[1mpwndbg: [0m[31m[0m[91mloaded 193 commands. Type [35mpwndbg [filter][0m[91m for a list.[0m [31m[1mpwndbg: [0m[31m[0m[91mcreated [35m$rebase[0m[91m, [35m$ida[0m[91m gdb functions (can be used with print/break)[0m 0x12c3 <main>: endbr64 0x12c7 <main+4>: push rbp 0x12c8 <main+5>: mov rbp,rsp 0x12cb <main+8>: push rbx 0x12cc <main+9>: and rsp,0xffffffffffffff80 0x12d0 <main+13>: sub rsp,0x100 0x12d7 <main+20>: mov DWORD PTR [rsp+0x7c],edi 0x12db <main+24>: mov QWORD PTR [rsp+0x70],rsi 0x12e0 <main+29>: mov rax,QWORD PTR fs:0x28 0x12e9 <main+38>: mov QWORD PTR [rsp+0xf8],rax ++++++++++++++++ option: 8 [31m[1mpwndbg: [0m[31m[0m[91mloaded 193 commands. Type [35mpwndbg [filter][0m[91m for a list.[0m [31m[1mpwndbg: [0m[31m[0m[91mcreated [35m$rebase[0m[91m, [35m$ida[0m[91m gdb functions (can be used with print/break)[0m 0x12c9 <main>: endbr64 0x12cd <main+4>: push rbp 0x12ce <main+5>: mov rbp,rsp 0x12d1 <main+8>: push rbx 0x12d2 <main+9>: and rsp,0xffffffffffffff00 0x12d9 <main+16>: sub rsp,0x200 0x12e0 <main+23>: mov DWORD PTR [rsp+0xfc],edi 0x12e7 <main+30>: mov QWORD PTR [rsp+0xf0],rsi 0x12ef <main+38>: mov rax,QWORD PTR fs:0x28 0x12f8 <main+47>: mov QWORD PTR [rsp+0x1f8],rax ++++++++++++++++ option: 9 [31m[1mpwndbg: [0m[31m[0m[91mloaded 193 commands. Type [35mpwndbg [filter][0m[91m for a list.[0m [31m[1mpwndbg: [0m[31m[0m[91mcreated [35m$rebase[0m[91m, [35m$ida[0m[91m gdb functions (can be used with print/break)[0m 0x12c9 <main>: endbr64 0x12cd <main+4>: push rbp 0x12ce <main+5>: mov rbp,rsp 0x12d1 <main+8>: push rbx 0x12d2 <main+9>: and rsp,0xfffffffffffffe00 0x12d9 <main+16>: sub rsp,0x400 0x12e0 <main+23>: mov DWORD PTR [rsp+0x1fc],edi 0x12e7 <main+30>: mov QWORD PTR [rsp+0x1f0],rsi 0x12ef <main+38>: mov rax,QWORD PTR fs:0x28 0x12f8 <main+47>: mov QWORD PTR [rsp+0x3f8],rax ++++++++++++++++ option: 10 [31m[1mpwndbg: [0m[31m[0m[91mloaded 193 commands. Type [35mpwndbg [filter][0m[91m for a list.[0m [31m[1mpwndbg: [0m[31m[0m[91mcreated [35m$rebase[0m[91m, [35m$ida[0m[91m gdb functions (can be used with print/break)[0m 0x12c9 <main>: endbr64 0x12cd <main+4>: push rbp 0x12ce <main+5>: mov rbp,rsp 0x12d1 <main+8>: push rbx 0x12d2 <main+9>: and rsp,0xfffffffffffffc00 0x12d9 <main+16>: sub rsp,0x800 0x12e0 <main+23>: mov DWORD PTR [rsp+0x3fc],edi 0x12e7 <main+30>: mov QWORD PTR [rsp+0x3f0],rsi 0x12ef <main+38>: mov rax,QWORD PTR fs:0x28 0x12f8 <main+47>: mov QWORD PTR [rsp+0x7f8],rax ++++++++++++++++ option: 11 [31m[1mpwndbg: [0m[31m[0m[91mloaded 193 commands. Type [35mpwndbg [filter][0m[91m for a list.[0m [31m[1mpwndbg: [0m[31m[0m[91mcreated [35m$rebase[0m[91m, [35m$ida[0m[91m gdb functions (can be used with print/break)[0m 0x12d5 <main>: endbr64 0x12d9 <main+4>: push rbp 0x12da <main+5>: mov rbp,rsp 0x12dd <main+8>: push rbx 0x12de <main+9>: and rsp,0xfffffffffffff800 0x12e5 <main+16>: sub rsp,0x1000 0x12ec <main+23>: or QWORD PTR [rsp],0x0 0x12f1 <main+28>: mov DWORD PTR [rsp+0x7fc],edi 0x12f8 <main+35>: mov QWORD PTR [rsp+0x7f0],rsi 0x1300 <main+43>: mov rax,QWORD PTR fs:0x28 ++++++++++++++++ option: 12 [31m[1mpwndbg: [0m[31m[0m[91mloaded 193 commands. Type [35mpwndbg [filter][0m[91m for a list.[0m [31m[1mpwndbg: [0m[31m[0m[91mcreated [35m$rebase[0m[91m, [35m$ida[0m[91m gdb functions (can be used with print/break)[0m 0x12e1 <main>: endbr64 0x12e5 <main+4>: push rbp 0x12e6 <main+5>: mov rbp,rsp 0x12e9 <main+8>: push rbx 0x12ea <main+9>: and rsp,0xfffffffffffff000 0x12f1 <main+16>: sub rsp,0x1000 0x12f8 <main+23>: or QWORD PTR [rsp],0x0 0x12fd <main+28>: sub rsp,0x1000 0x1304 <main+35>: or QWORD PTR [rsp],0x0 0x1309 <main+40>: mov DWORD PTR [rsp+0xffc],edi
-m32, -m64 무관하게 디폴트는 N=4 이고, 따라서 모든 함수의 스택 프레임의 최하위주소가 16의 배수가 됨.
관련 gcc 소스코드
64bit은 default 와 N=3 에서 and 연산 없이 align을 해주는데, 이는 _start 에서 (32bit, 64bit 무관하게) 0xfffffff...ff0 과 Stack Pointer 를 xor 시키고 시작하기 때문에, 64bit 기준 main 에 진입할 시점은 sp 의 LSB가 0x8 이 됨 (0x10 - 0x8(return address)) 여기서 rbp 와 rbx 를 push하기 때문에 LSB 는 변하지 않음
물론, __libc_start_main 을 거쳐 가기는 하지만, 이곳에서는 align 을 고려하지 않고 default 로 생각하며 N=4 만 맞추어진 상태이다(이미 라이브러리는 N=4, 즉 디폴트로 컴파일 되었기 때문)
따라서 main 에 진입했을 때도, LSB 가 0x8 인 상태라고 볼 수 있음
따라서 main 에서는 LSB가 0x8 인 Constant 로 rsp 를 감소시켜주기만 하면 N=4 조건까지 충족시키기 때문에, 64bit 바이너리에서 N≤4 일 때 rsp 를 and 시켜주지 않아도 됨
N=3 일 때는 사실 64bit 이 8바이트 단위이기 때문에 당연히 align 되어있기 때문에 무시하자.
N = 4 일 때 다른 함수를 부르게 되면 마찬가지로 return address 가 차지하는 공간으로 rsp 의 LSB 가 0x8 이 되고 rbp 를 push 하면서 다시 16의 배수가 되기 때문에, 적당한 16의 배수 constant 를 빼줌으로 N=4 align 을 맞추는 것을 볼 수 있다.
반면, 32bit 의 경우는 default 가 N=4 이고 block 단위가 4바이트이기 때문에 and 연산으로 esp 를 16에 align 시키는 것을 볼 수 있다.
반면 N=2 인 경우, 명령어에 아무런 변화없이도 기본적으로 4의 배수가 성립되므로 align 을 위한 명령어가 추가되지 않는 것을 볼 수 있음 → 분석에 용이
그렇다면 32bit 에서는 기본적으로 인자를 스택에 전달하고, 64bit 에서는 7번째 인자부터는 스택에 전달하는데, 위에서 고생하며 align 맞춘거를 다 깨버리지 않을까?
- 그래서 push 하기 전에, 적절한 상수로 esp 를 낮춰줌으로써 자연스럽게 call 하기 직전에 align 이 되어있도록 함
64bit 은 (main 함수 기준으로) 인자가 레지스터에 있기 때문에 뭐 레지스터에서 읽어오면 되는데, 32bit 은 main 에서 align 을 하고 ebp 를 쌓고, 인자는 ebp 기준으로 가져와야할텐데 어떻게 하지??
- and 이후에 ebp 를 쌓기 때문에, 인자들이 ebp 를 기준으로 얼마나 떨어졌는지 알 방법이 없어진다.
- 이제는 ecx 가 인자들이 위치하는 시작주소를 가리키는 포인터가 된다. (
lea ecx, [esp + 0x4]
)
- 따라서 argc 를 출력하는 프로그램에서 [ecx] 에서 인자를 가져오는 것을 볼 수 있다.
그리고 main 이후에 불리는 함수에서는??
- N align 을 맞춘 상태에서 함수 foo 를 부름
- foo 에 진입할 때는 N align - 4 일 것이고, 이제 ebp와 callee saved register 를 push 한 후에 sub esp, CONST 를 적절히 연산해줌으로 다시 stack frame 을 align 시킴
- 이제는 ebp 에서 인자를 읽어오면 됨(별다른 align 과정이 없었기 때문에)
Uploaded by Notion2Tistory v1.1.0