cf> 메모리를 그릴 때
1> 보통
위 = 낮은 주소 (00000000)
아래 = 높은 주소 (FFFFFFFF)
로 그린다.
2> stack
하지만 stack은 decrement의 느낌을 주기 위해 반대로 그림을 그린다.
1. Stack Operations
1) Runtime Stack
1> stack
- LIFO (Last In First Out)
- 한 쪽 끝(top)에서만 삽입과 삭제가 일어나는 구조
(Stack을 그릴 때는 평소(위 = 낮은 주소, 아래 높은 주소)와 반대로 그린다.)
2> Stack Pointer
- stack을 가리키는 pointer (TOP)
- stack frame에서 stack의 가장 마지막 주소가 저장된다.
- SS register가 가리키는 stack segment의 맨 꼭대기를 가리키는 pointer
- 32-bit에서는 ESP, real-address(16-bit) 구조에서는 SP
3> Stack Segment (SS register)
cf> 32-bit 체제에서는 메모리 한 칸 이동할 때마다 4씩 차이가 난다.
2) PUSH
1> 과정
- SP(stack pointer)가 4byte(stack element size in 32-bit)만큼 decrement
- SP가 가리키는 곳에 값을 저장
2> 특징
- stack은 아래 방향으로 증가한다.
- SP 아래로는 사용할 수 있는 메모리이다. (overflow가 일어나지 않는 한)
3) POP
1> 과정
- SP가 가리키는 값을 다른 register나 variable로 copy
- (복사한 후) SP에 4byte(stack element size in 32-bit) or 2byte만큼 increment-> SP가 가리키는 값을 제거
- SP가 4byte(stack element size in 32-bit)만큼 increment
4) stack 구조 예시
1> PUSH와 POP 예시
push esi ; push registers
push ecx
push ebx
mov esi, OFFSET dwordVal ; display some memory
mov ecx, LENGTHOF dwordVal
mov ebx, TYPE dwordVal
call DumpMem
pop ebx ; restore registers
pop ecx
pop esi
- push와 pop은 반대의 순서로 일어난다.
- call DumpMem : esi, ecx, ebx가 DumpMem의 parameter로 넘어간다. (register로 parameter passing 한다.)
- 원래는 DumpMem도 loop를 돌면서 3번 출력을 하기 때문에 ECI가 필요하다.
=> register의 값을 임시적으로 저장히기 위해 push
=> DumpMem이 끝나고 나서 pop
2> Nested Loop
mov ecx, 100 ; set outer loop count
L1: ; begin the outer loop
push ecx ; save outer loop count
; ### INNER LOOP START ###
mov ecx, 20 ; set inner loop count
L2: ; begin the inner loop
;
;
loop L2 ; repeat the inner loop
; ### INNER LOOP END ###
pop ecx ; restore outer loop count
loop L1 ; repeat the outer loop
- loop를 중첩하니 ECX가 혼란이 생길 수 있다.
- 그래서 outer loop에서 ECX를 임시 저장하기 위해 push를 사용한다.
- (line 3) push ecx : 첫 번째 loop의 counter를 잠시 stack에 저장
- (line 5) mov ecx, 20 : 두 번째 loop의 counter를 (20으로) 할당 받는다.
- (line 11) pop ecx : 첫 번째 loop의 counter를 다시 받는다.
3> Reversing a String
- 기본 원리 : 각 글자(character)를 stack에 push
.data
aName BYTE “I like StarII",0
nameSize = ($ - aName) - 1 ; nameSize = 12
.code
mov ecx,nameSize
mov esi,0
L1: movzx eax,aName[esi] ; get character
push eax ; push on stack
inc esi
Loop L1
mov ecx,nameSize
mov esi,0
L2: pop eax ; get character
mov aName[esi],al ; store in string
inc esi
Loop L2
cf> Related Instruction
1> PUSHFD, POPFD : EFLAG register들 push & pop
2> PUSHAD, POPAD
PUSHAD : 32-bit general-purpose register들을 stack에 push
(order : EAX, ECX, EDX, EBX, ESP, EBP, ESI, EDI)
POPAD : 32-bit general-purpose register들을 stack에 pop in reverse order
3> PUSHA, POPA : 16-bit general-purpose register들을 stack에 push & pop
'Assembly' 카테고리의 다른 글
5-3강 - Procedure 3 (Link Library) (0) | 2020.05.21 |
---|---|
5-2강 - Procedure 2 (Procedure) (0) | 2020.05.21 |
4-4강 - Data Transfer, Addressing and Arithmetic 4 (Indirect Addressing, JMP & LOOP) (0) | 2020.05.19 |
4-3강 - Data Transfer, Addressing and Arithmetic 3 (Data-Related Operators and Directives) (0) | 2020.05.18 |
4-2강 - Data Transfer, Addressing and Arithmetic 2 (Addition and Subtraction) (0) | 2020.05.18 |