Assembly
Push
Push는 ESP의 주소를 감소시키고 Stack에 값을 넣는것을 말한다.
1. ESP의 주소를 감소 시킨다.
2. 감소시킨 주소에 값을 넣는다.
3. Push 후의 ESP는 마지막으로 값을 넣은 주소의 위치로 이동한다.
Pop
Pop은 Push와 반대로 Stack에 있는 값을 추출하고 주소를 증가시킨다.
1. Stack에 있는 값을 추출한다.
2. ESP의 주소를 증가시킨다.
3. 증가한 ESP의 값은 추출한값의 앞으로 이동한다.
※ Windows 8.1 사용으로인하여 Windbg가 아닌 Immunity로 테스트를 하였으므로 여러분들과의 테스트화면이 다름을 알려드립니다.
Push, Pop 기본 코드
Push
실행 초기 Stack의 시작과 끝을 가리키는 EBP, ESP의 주소는 0x0013FF94, 0x0013FF84로 되어있다.
메모리에서의 파란색은 EBP, 회색은 ESP이다.
두 단계를 실행한 후에는 AX가 2Byte이므로 ESP는 2Byte 감소한 0x0013FF82로 변경되었다.
메모리에서 현재 ESP의 주소에는 AX를 Push 했기때문에 AX의 값 B583이 들어있다.
실제의 값은 B583이지만 Stack에는 빅인디안에서 리틀인디안으로 변경이되어 저장이 되므로 83B5로 저장이 되어있다.
0XFFFFFF10 4Byte를 다시한번 Push하면 이전 ESP의 주소에서 4Byte만큼 감소되는것을 볼수있다.
4Byte만큼 감소된 ESP의 주소에는 0xFFFFFF10이 리틀인디안으로 변경되어서 0x10FFFFFF으로 저장된걸 볼수있다.
Pop
Pop을 통하여 Stack에 있는것을 EBX으로 빼보았는데 먼저 ESP의 주소가 다시 EBX의 크기만큼 즉 4Byte만큼 증가된걸 볼수 있다.
ESP의 주소는 증가가되고 EBX에는 ESP로부터 4Byte만큼의 값인 0xFFFFFF10이 들어가있다.
Stack에서 레지스터로 Pop을 할때는 리틀인디안에서 빅인디안방식으로 다시 변경되기 때문에 0xFFFFFF10으로 저장되는것을 볼수 있다.
메모리에서 ESP의 주소를 보면 처음 AX를 Push를 했던 0x0013FF82로 증가되어 이동되어있고 그곳의 값은 Push 했던것과 같게 B583이 들어있는것을 볼수 있다.
ECX를 0으로 채워 CX에 Pop을 할때 어떤값이 들어가는지 좀 더 잘 볼수있다.
ECX에 0을 MOV를 통하여 채우고난 뒤 CX에 Pop을 하면 CX의 크기만큼 2Byte ESP가 중가되고 CX에 중가된 2Byte만큼의 값이 채워지게된다.
Pop후 ECX 레지스터를 보면 0x000083B5로 빅인디안으로 변환되어 저장되어있는 것을 볼수 있다.
ESP의 주소는 동일한 크기로 Push와 Pop을 했기때문에 처음 시작과 같은 0x0013FF84로 돌아온것을 볼수 있다.
모든 Register를 Push, Pop을 할수있는 Pushed, Popad
Pushad
모든 Register를 Push하는 Pushad는 EAX, ECX, EDX, EBX, ESP, EBP, ESI, EDI순서대로 Push가 된다.
이렇게 모든 Register를 Push하기 위해서 그리고 그 Push된 결과를 좀 더 쉽게 확인하기 위해서 모든 Register에 값을 먼저 넣는다.
단! EBP, ESP는 값을 넣지않는다. 왜냐면 EBP, ESP는 Stack의 시작과 끝을 가리키고있기때문에 EBP, ESP에 값을 넣게되면 Stack을 가리키는 주소가 틀어지게 되므로 건들지 않도록한다. 그리고 EBP와 ESP의 값을 확인해야하는데 여기서는 EBP(Stack의 시작)는 0x0013FF94, ESP(Stack의 끝)는 0x0013FF84이다.
메모리상의 EBP는 0x0013FF94, ESP는 0x0013FF84 이다.
Pushad를 하게되면 EAX, ECX, EDX, EBX, ESP, EBP, ESI, EDI 각 4Byte 8개의 Register 총 32Byte가 Push되어진다.
주소를보면 초기의 ESP는 0x0013FF84에서 ESP 0x0013FF64로 감소되었다. 16진수로 20차이지만 10진수로 변환되면 32가 나오는데 이 숫자는 각 4Byte 8개 Register 크기와 동일하다.
메모리를 통해서 보면 EBP, ESP의 공간을 제외하고는 모두 초기에 지정한값들이 들어가있다.
EBP, ESP의 공간들은 이전의 EBP, ESP에 들어있던 0x0013FF94, 0x0013FF84가 들어있다.
이렇게 모든 값들이 EAX, ECX, EDX, EBX, ESP, EBP, ESI, EDI 순서대로 저장이 된걸 볼수 있다.
우리가 Pop을 할때 해당위치에 있는값을 가져오고 주소를 증가시키는지 아니면 주소만 증가시키는지를 확인하기위해서 이번코드를 넣었다.
현재 메모리에는 0x0013FF70이라는 주소에 이전의 ESP값 0x0013FF84가 들어있다. 만약 이상태로 Popad를 하게되면 이전의 값과 같은값이 들어가기때문에 값이 추출되고 들어가는지 그렇지 않은지를 알수 없기에 현재 사용하지 않은 EBX에 이전의 ESP의 값이 들어있는 주소 0x0013FF70을 상수형식으로 넣고 그 상수값을 포인터 형식으로 변환시켜 가르키는 곳에 0을 넣고 Popad를 한후 ESP의 공간에 0이 들어가는지 확인을 해본다. Assembly에서 상수를 포인터 형식으로 사용하는 문법이 DWORD PTR[EBX] 이런형식으로 사용된다.
EBX를 포인터형식으로 ESP 공간에 0을 넣기 전 메모리 상태
포인터형식을 이용하여 ESP의 값이있는 공간에 0을 넣고난 화면
EBX에는 ESP의 값이있는 메모리주소 0x0013FF70이 들어있다.
메모리의 주소 0x0013FF70의 값은 포인터형식으로 넣었던 0이 들어있는걸 알수 있다.
마지막으로 Popad가 되는것을 확인하기 위해서 아까와 다른 값인 0으로 모든 Register를 채운다. (EBP, ESP를 제외한 Register)
그리고 Popad를 하면 이전에 Pushad를 한 값들이 Register로 돌아오는것을 볼수 있다.
ESP는 Pushad 하기전의 값으로 돌아온다. EBP는 변동이 없다.
'코스웨어 > 15년 스마트컨트롤러' 카테고리의 다른 글
20151008 - 김성주 - M3 : RCC / 어셈블리 : pushad를 이용한 구조체 삽입 (6) | 2015.10.08 |
---|---|
20151007 - 권오민 - GPIO&AFIO / ASSEMBLY(C와 링크하기) (3) | 2015.10.07 |
201501006 - 2번 강동조 (오전: GPIO -LED 오후: ) (5) | 2015.10.06 |
20151005 - 홍준모 (오전 : ARMCortexM3, 오후 : Assambly) (5) | 2015.10.05 |
20150930-주재민-일일업무일지-어셈블리 (7) | 2015.10.01 |
20150930-26번-임현수-일일업무일지-취업특강, 어셈블리 loop 명령 (6) | 2015.10.01 |
20150925-23번-이량경-일일업무일지-ASM {jum, cmp}/ 적외선 온도 감지 센서 (6) | 2015.09.30 |
20510924-23번-윤재희 적외선 센서 코딩, 큰 수의 덧셈과 뺄셈, 분기와 순환 (4) | 2015.09.24 |