임베디드/임베디드 레시피

stack 메모리 dump

twoweeks-within 2024. 12. 7. 00:36

 

 Stack을 뒤져 보고, Back tracing도 해보기

 ( Thumb mode의 Full Descending Stack )

N _  R0       FFFE       R8          0
Z Z  R1          0            R9          0
C C  R2       5074     R10         0
V _  R3   1E6C1A35  R11         0
I _  R4          0             R12         0
F _  R5          0           R13  1F6E92C8
T T  R6       FFFF        R14  1E6C1A1D
J _  R7   1F6E943C  PC   1E6C19BC
usr  SPSR                 CPSR 60000030
Q _
A _  USR:                  FIQ:
E _  R8          0          R8          0
     R9          0            R9   C5400100
0 _  R10         0          R10  1F62C9F0
1 _  R11         0           R11  F00898F0
2 _  R12         0          R12        DD
3 _  R13  1F6E92C8   R13         1
         R14  1E6C1A1D   R14  F0008BFC
                                    SPSR        10
     SVC:                     IRQ:
     R13  E000A880  R13  F008CD00
     R14  F0000000  R14  1DB55BF8
     SPSR 60000010  SPSR 60000010

     UND:                    ABT:
     R13  60000010  R13  00100000
     R14  1DB55BF8  R14  1EFCE4BE
     SPSR 60000010  SPSR 20000030

 


 CPSR > User Mode

Thumb mode // CPSR의 T 비트 확인

     0x6000 0030 == 0110 0000 0000 0000 0000 0011 0000

     T 비트 : CPSR[5]  // 1 :thumb mode

 

 IRQ, FIQ는 enable //  0 : enable

      I 비트 (Interrupt Disable): CPSR[7]

      F 비트 (Fast Interrupt Disable): CPSR[6]

 

 현재 PC값 :  0x1E6C19BC

 

addr/line__|code_____|label____|mnemonic________________|comment________
           |
           |word b_funct(word arg, word param)
       3958|{
ST:1E6C19B8|B570      b_funct:        push    {r4-r6,r14}
ST:1E6C19BA|B0B2                sub     sp,#0xC8
           |          int loop;
       3960|        word ret = 0;
ST:1E6C19BC|2400                mov     r4,#0x0
           |        word array[100];
           |
       3963|        for (loop=0; loop < 100; loop++)
ST:1E6C19BE|2200      mov  r2,#0x0
ST:1E6C19C0|466E                cpy     r6,r13
           |        {
       3965|                if (loop%2)
ST:1E6C19C2|07D3                lsl     r3,r2,#0x1F      ; r3,loop,#31
ST:1E6C19C4|D002                beq     0x1E6C19CC
       3966|                        array[loop] = arg;

 

 

word b_funct (word arg, word param) 이라는 함수를 실행하던 중..

   > 그러면, 이 함수를 부른 녀석은?

 > Register값들을 Stack에 Push했는지 확인 후 R13 (Stack Pointer)확인

 

 

ST:1E6C19B8|B570 b_funct: push {r4-r6,r14}
ST:1E6C19BA|B0B2 sub sp,#0xC8

 

b_funct()에 진입> r4~r6, r14 push
  sub sp-0xc8 를 한 이유??

 ( local variable을 stack에 넣음 )

 

 b_funct()함수

 

  local variable로 word array[100]을 잡아 놓음

// word : 4byte > 400byte 크기

   > stack에 이 array를 임시로 잡기 위해 >  0xc8 (십진수로 200)을 예약 

stack pointer : r4~r6, r14를 push > 200개의 자리를 더 잡아 놓음

 

stack pointer : r4~r6, r14를 push > 200개의 자리를 더 잡아 놓음 > 더 작은 주소로 Stack이 자라남

    > stack pointer의 주소를 빼면,, 400 - 200 == 200 만큼의 공간 더 생김 (낮은 주소로 향하는)

 


SP값 :   (r13) + 200을 해주면 찾을 수 있음


0x1F6E92C8 + 0xC8의 메모리 상태..

 

d.dump 0x1F6E92C8+0xC8 = 0x1F6E9390 (r14의 값)

 

___address__|________0________4________8________C_0123456789ABCDEF
 SD:1F6E9390|>00000000 00000000 0000FFFF 1E6C1A1D ..............l.
 SD:1F6E93A0| 00000000 1E6C1A59 00005074 1C87DE49 ....Y.l.tP..I...
 SD:1F6E93B0| 1F6E93C8 1F42F291 00000000 00000000 ..n...B.........
       "

     "
 SD:1F6E94F0| 1F6E9370 1F6E936C 00000001 1F6E9410 p.n.l.n.......n.
 SD:1F6E9500| 1F6E939C 1F6E9368 00000000 00000001 ..n.h.n.........

 

 

___address__|________0________4________8________C_0123456789ABCDEF
SD:1F6E9390|>00000000 00000000 0000FFFF 1E6C1A1D ..............l.
                                            r4              r5                 r6       r14

 

요렇게 되겠네요. 0x1E6C1A1D :  r14 의 값

// sp : 1F6E9390 주소에 R14가 담겨있는데 그 값은 1E6C1A1D ( 라는 주소 가 담겨있음 )

// stack pointer : 현재 위치의 주소를 담고있는 포인터 레지스터

// push {r4-r6,r14} : 4*4 만큼의 sp 이동 

   > 0x2000 > 0x1FF0

 

 

N _  R0       FFFE         R8          0
Z Z  R1          0              R9          0
C C  R2       5074         R10         0
V _  R3   1E6C1A35      R11         0
I _  R4          0                 R12         0
F _  R5          0              R13  1F6E92C8
T T  R6       FFFF           R14  1E6C1A1D
J _  R7   1F6E943C       PC   1E6C19BC
usr  SPSR                  CPSR 60000030

 


b_fucnt()함수를 부른 놈 : 0x1E6C1A1D 근방

 

정확히 말해 b_funct()함수를 처리하고 돌아가서 계속 진행할 주소 : 0x1E6C1A1D  > 한 line위

 주의)  Thumb mode이니까 0x1E6C1A1D-1 = 0x1E6C1A1C로 돌아가야함

 

addr/line__|code_____|label____|mnemonic________________|comment______________________________________________________|
           |word a_funct(word arg, word param)
       3985|{
ST:1E6C1A10|B510      a_funct:        push    {r4,r14}
           |        int localone, localtwo;
           |        word ret;
           |
       3989|        localone = (int)(arg<<1);
ST:1E6C1A12|0040                lsl     r0,r0,#0x1       ; arg,arg,#1
       3990|        localtwo = (int)(param>>1);
ST:1E6C1A14|0849                lsr     r1,r1,#0x1       ; param,param,#1
           |
       3992|        ret =  b_funct ((word)localone, (word)localtwo);
ST:1E6C1A16|B280                uxth    r0,r0            ; localone,localone
ST:1E6C1A18|FFCEF7FF            bl      0x1E6C19B8       ; b // 여기
ST:1E6C1A1C|4604                cpy     r4,r0
           |
       3994|        if (ret>100)
ST:1E6C1A1E|2C64                cmp     r4,#0x64         ; ret,#100
ST:1E6C1A20|D903                bls     0x1E6C1A2A
       3995|            message ("too big");
ST:1E6C1A22|A078                add     r0,pc,#0x1E0
ST:1E6C1A24|ED62F0AE            blx     0x1E7704EC
ST:1E6C1A28|E002                b       0x1E6C1A30
           |        else
       3997|            message ("appropriate");
ST:1E6C1A2A|A078                add     r0,pc,#0x1E0
ST:1E6C1A2C|ED5EF0AE            blx     0x1E7704EC
           |
       3999|        return ret;
ST:1E6C1A30|4620                cpy     r0,r4            ; r0,ret
       4000|}
ST:1E6C1A32|BD10                pop     {r4,pc}
           |


 b_funct함수를 부르는 함수 : a_funct함수

 

 bl      0x1E6C19B8  > r14 : PC +4  = 1E6C1A18 

> 이동 : 0x1E6C19B8 

 

 a_funct함수를 부른 놈 찾기

 

___address__|________0________4________8________C_0123456789ABCDEF
SD:1F6E9390|>00000000 00000000 0000FFFF 1E6C1A1D ..............l.   //  r14
SD:1F6E93A0| 00000000 1E6C1A59 00005074 1C87DE49 ....Y.l.tP..I...  // b_funct()
SD:1F6E93B0| 1F6E93C8 1F42F291 00000000 00000000 ..n...B.........
SD:1F6E93C0| 00000000 00000000 1F6E943C 1F3FB721 ........

 

그럼, b_funct()가 불렸을 때 SP : 0x1F6E93A0 // a_fuct()의 sp를 넣음

 

     a_funct()함수가 불렸을 때 Stack..

 

addr/line__|code_____|label____|mnemonic________________|comment______________________________________________________|
           |word a_funct(word arg, word param)
       3985|{
ST:1E6C1A10|B510      a_funct:        push    {r4,r14}
           |        int localone, localtwo;

 >  r4,r14를 push 그러면

 

SD:1F6E93A0| 00000000 1E6C1A59 00005074 1C87DE49
                                       r4           r14

 r14-1 (= 0x1E6C1A58)의 주소 > a_funct()함수를 부르고 다음 실행할 주소

 

_addr/line__|code_____|label____|mnemonic________________|comment
        4032|          arg_ex = Index;
 ST:1E6C1A50|4630                cpy     r0,r6            ; r0,Index
            |
        4034|          ret2 = a_funct(arg_ex, (word)data);
 ST:1E6C1A52|2101                mov     r1,#0x1
 ST:1E6C1A54|FFDCF7FF            bl      0x1E6C1A10       ; a
 ST:1E6C1A58|9003                str     r0,[r13,#0x0C]   ; arg_ex,[r13,#12]


0x1E6CA58 바로 한 칸 위를 보면 a_funct() 함수를 호출한 곳 0x1E6C1A10    

 

R13에 엮여 있는 주소에 뭔가를 push하고, pop

   > R13에 주소를 넣기만 하면 그 주소부터 push/pop하면서 장난 친다는 사실! 

 

왜 Local 변수가 없어질 수 밖에 없는가?

  > 일반 Symbol과는 달리 Stack에 저장  > 되니까 개인 Address가 없음

   > 쓰고 나면 없어짐!

'임베디드 > 임베디드 레시피' 카테고리의 다른 글

함수 포인터와 실행 주소 변경  (0) 2024.12.08
Stack의 Size  (0) 2024.12.07
stack : 함수를 불렀을때  (1) 2024.12.06
stack initialization  (0) 2024.12.05
Stack , Heap  (0) 2024.12.05