2011-08-14 17 views
1

我稍微拆卸以下有點困惑:在臂組件使用堆棧指針(SP)的

_GSEventLockDevice: 
000047d8  b5f0 push {r4, r5, r6, r7, lr} 
000047da  af03 add r7, sp, #12 
000047dc  b08d sub sp, #52 
000047de f7ffffb3 bl _GSGetPurpleSystemEventPort 
000047e2  466d mov r5, sp 
000047e4  2234 movs r2, #52 
000047e6  2100 movs r1, #0 
000047e8  4604 mov r4, r0 
000047ea  4628 mov r0, r5 
000047ec f005e8b0 blx 0x9950 @ symbol stub for: _memset 
000047f0  2600 movs r6, #0 
000047f2 f24030f6 movw r0, 0x3f6 
000047f6  4621 mov r1, r4 
000047f8 e88d0041 stmia.w sp, {r0, r6} 
000047fc  4628 mov r0, r5 
000047fe f7fffaf7 bl _GSSendEvent 
00004802  b00d add sp, #52 
00004804  bdf0 pop {r4, r5, r6, r7, pc} 
00004806  bf00 nop 

我不明白這是如何會去C.唯一位我得到的是:

memset(whateverTheStackPointerIs, 0, 52); 

但是我怎麼知道sp是什麼以及它在C中看起來如何?

回答

3

sub sp, #52 

保留52個字節的空間,在堆棧上的局部變量;之後sp將指向這52個字節中的第一個。他們都隨着memset調用歸零。在memset之後,stmia在前兩個字中存儲特定值。所以C等價物就像

GEEventLockDecvice() { 
    int tmp = GSGetPurpleSystemEventPort(); 
    int localdata[13] = {0}; 
    localdata[0] = *0x3f6; 
    localdata[1] = 0; 
    return GSSendEvent(&localdata, tmp); 
} 
+0

+1看起來很忠實。 '* 0x3f6'雖然不合法C.我認爲在這種情況下它應該是'*(volatile uint16_t *)0x3f6'。或者它是加載32位值,然後是'uint32_t'。 – user786653

+0

我認爲ARM上的'.w'表示32位。 ARM語言中的16位將是「半字」。 –

+0

什麼時候你會通過寄存器使用堆棧? – Johnathon