130924화 어셈블리 과제 조유진
소스
.386
.MODEL FLAT
PUBLIC _STST ; Store Status
PUBLIC _LDST ; Load Status
.CODE
_STST PROC NEAR32
PUSH EBP
MOV EBP, ESP
PUSHFD
AND DWORD PTR [EBP-4], 0FFFFFEFFh
MOV ESP, [EBP+8]
ADD ESP, 40
PUSHAD
ADD ESP, 16
;Old EBP, RA, 인자, Main과의 경계
MOV EAX, EBP
ADD EAX, 8
PUSH EAX ; 메인 ESP
PUSH [EBP] ; Old EBP
SUB ESP, 8
PUSH [EBP+4] ; EIP(Return Address)
PUSH [EBP-4] ; EFL
MOV ESP, EBP
POP EBP
RET
_STST ENDP
_LDST PROC NEAR32
MOV ESP, [ESP+4] ; ESP = &Context
POPFD ; EFL = Context.EFL
; 플래그 레지스터에 값을 넣음
POP EAX ; EAX = Context.EIP
; 예전 EIP를 EAX 저장
MOV EBX, ESP ; EBX = Current ESP
; 현재 ESP 백업
MOV ESP, [ESP+12] ; ESP = Old ESP
; 과거 ESP로 점프
PUSH EAX ; Save Old EIP
; 과거 ESP에 EAX를 푸쉬하여 RA덮어씀
MOV ESP, EBX ; ESP = Current ESP
; 백업해둔 ESP를 다시 복원
POPAD ; ESP를 제외한 모든 값을 복원
MOV ESP, [ESP-20] ; Old ESP값을 복원
SUB ESP, 4 ; ESP를 RA위로 올려주어야 한다(RET이 POP하기때문)
RET
_LDST ENDP
END
결과 사진
첫번째 0000은 제일 초기값, 두번째는 STST를 실행한 직후의 값, 세번째는 LDST를 실행하여 STST를 실행한 직후로 옮겨버린 값이다.
pushad는 스택에 저장하므로 ESP까지 저장하고, ESP에 지장을 주지 않으나 popad는 ESP값을 변경하면 POP연산에 영향을 줄 수 있으므로 ESP를 무시하는 게 아닌가 멋대로 추측해 본다. 무시하여도 ESP의 위치는 자동으로 건너뛰어준다.(직접 ESP를 옮겨줄 필요가 없다)