2011-11-06 15 views
8

So che quando si chiama una funzione in assembly r0 contiene il primo argomento fino a r3 è il quarto. So che quando va oltre il 4 viene usato il puntatore dello stack ma non sono troppo sicuro sulle specifiche. R0-r3 tiene ancora i primi quattro e il resto va in pila? Sto guardando il seguente pezzo di assemblaggio cercando di capire cosa sta facendo per chiamare mach_msg (una funzione con sette argomenti). Al momento dell'ingresso a questo codice, r0 e r1 contengono i due argomentiAssieme braccio - Funzione di chiamata con più di 4 argomenti

var_38   = -0x38 
var_34   = -0x34 
var_30   = -0x30 
var_2C   = -0x2C 
var_24   = -0x24 
var_20   = -0x20 
var_18   = -0x18 
var_14   = -0x14 
var_10   = -0x10 
var_C   = -0xC 
00001220 
00001220     PUSH   {R7,LR} 
00001222     MOV    R7, SP 
00001224     SUB    SP, SP, #0x30 
00001226     MOV    R2, (_NDR_record_ptr - 0x1232) ; _NDR_record_ptr 
0000122E     ADD    R2, PC ; _NDR_record_ptr 
000LDR    R2, [R2] ; _NDR_record 
000LDR    R3, [R2] 
000LDR    R2, [R2,#4] 
000STR    R2, [SP,#0x38+var_10] 
000MOVS   R2, #0x24 ; '$' 
0000123A     STR    R3, [SP,#0x38+var_14] 
0000123C     MOVS   R3, #0 
0000123E     STRB.W   R1, [SP,#0x38+var_C] 
00001242     MOVS   R1, #0x13 
00001244     STR    R1, [SP,#0x38+var_2C] 
00001246     MOVS   R1, #1 
00001248     STR    R0, [SP,#0x38+var_24] 
0000124A     MOV    R0, 0x1E84EA 
00001252     STR    R3, [SP,#0x38+var_20] 
00001254     STR    R3, [SP,#0x38+var_38] 
00001256     STR    R3, [SP,#0x38+var_34] 
00001258     STR    R0, [SP,#0x38+var_18] 
0000125A     STR    R3, [SP,#0x38+var_30] 
0000125C     ADD    R0, SP, #0x38+var_2C 
0000125E     BLX    _mach_msg 
00001262     ADD    SP, SP, #0x30 
00001264     POP    {R7,PC} 

Qui ci sono le definizioni per la roba chiamati e utilizzati:

typedef struct { 
    unsigned char  mig_vers; 
    unsigned char  if_vers; 
    unsigned char  reserved1; 
    unsigned char  mig_encoding; 
    unsigned char  int_rep; 
    unsigned char  char_rep; 
    unsigned char  float_rep; 
    unsigned char  reserved2; 
} NDR_record_t; 
extern NDR_record_t NDR_record; 
extern mach_msg_return_t mach_msg(
       mach_msg_header_t *msg, 
       mach_msg_option_t option, 
       mach_msg_size_t send_size, 
       mach_msg_size_t rcv_size, 
       mach_port_name_t rcv_name, 
       mach_msg_timeout_t timeout, 
       mach_port_name_t notify); 

Da quello che ho capito, lo stack pointer viene invertita 48 byte per variabili. Sono 48 byte per gli argomenti extra 3 o per tutti loro?

risposta

6

Dei 48 byte, 12 sono per i 3 parametri aggiuntivi e gli altri per le variabili locali. Puoi vedere questo nel codice in cui la funzione passa quattro parametri in r0 a r3, un altro in [SP, # 0x38 + var_38] (che se fai il calcolo matematico si risolve solo in [sp]), un altro in [sp, # 4 ] e l'ultimo in [sp, # 8].

+0

Quindi fare gli argomenti rimanenti iniziano dall'inizio del puntatore dello stack? – user1000039

+0

Giusto, questo è ciò che significa "[sp]". –

0

Ricordo che tutti quelli che possono essere passati attraverso i registri (r0-r3 o 4 parole) sono passati attraverso i registri. e il resto viene passato attraverso lo stack.

1
unsigned int fun 
(
    unsigned int a, 
    unsigned int b, 
    unsigned int c, 
    unsigned int d, 
    unsigned int e, 
    unsigned int f 
) 
{ 
    a+=1; 
    a|=b+2; 
    a&=c+4; 
    a^=d+5; 
    a-=e+6; 
    a|=~f; 
    return(a); 
} 


00000000 <fun>: 
    0: e2800001 add r0, r0, #1 
    4: e2811002 add r1, r1, #2 
    8: e181c000 orr ip, r1, r0 
    c: e2822004 add r2, r2, #4 
    10: e002100c and r1, r2, ip 
    14: e59d0000 ldr r0, [sp] 
    18: e2833005 add r3, r3, #5 
    1c: e023c001 eor ip, r3, r1 
    20: e59d1004 ldr r1, [sp, #4] 
    24: e060200c rsb r2, r0, ip 
    28: e2420006 sub r0, r2, #6 
    2c: e1e03001 mvn r3, r1 
    30: e1800003 orr r0, r0, r3 
    34: e12fff1e bx lr 

I primi quattro sono r0 = a, r1 = b, r2 = c, r3 - d, in ordine, e poi il resto sono spinte in modo inverso in modo che sp + 0 è posta e sp + 4 è f.

Se si dispone di dire un intero a 64 bit quindi che avrà due registri, così si potrebbe utilizzare fino R0-R3 con quattro interi o due int e un lungo tempo, o due long lunghi, ecc

Problemi correlati