2012-12-27 14 views
5

Wiedziałem, że zmienne rejestrów są przechowywane w rejestrach procesora.Skąd wiadomo, gdzie przechowywana jest zmienna rejestru?

Te same zmienne są przechowywane w stosie, jeśli rejestry procesora są zajęte/pełne.

Skąd wiadomo, że zmienna jest przechowywana w rejestrze stosu lub CPU?

+1

The Jedynym sposobem, aby dowiedzieć się na pewno, jest zbadanie wyjściowego języka asemblera z twojego kompilatora –

+0

twoje założenia są błędne i na ostatnie pytanie nie można odpowiedzieć, ponieważ nie masz bezpośredniej kontroli w tym zakresie. – user1824407

+0

@GregHewgill naprawdę nie, również są zmienne takich jak ilość pamięci podręcznej zależnych od sprzętu i nie można przewidzieć, ile pamięci podręcznej będzie mieć procesor. możesz przeczytać swój montaż: o co ci chodzi? – user1824407

Odpowiedz

6

jestem zgodzić się z panem Zrelaksować na answer, ale do września niektóre przedłużyć ten sposób mogą być pomocne dla Ciebie:

nazwa pliku x.c:

int main(){ 
    register int i=0; 
    i++; 
    printf("%d",i); 
} 

Złożyć Kod:

~$ gcc x.c -S 

nazwa pliku wyjściowego to x.s.

W moim przypadku rejestr ebx jest używany, , co może być różnicą w różnych czasach kompilacji.

~$ cat x.s 
    .file "x.c" 
    .section .rodata 
.LC0: 
    .string "%d" 
    .text 
.globl main 
    .type main, @function 
main: 
    pushl %ebp 
    movl %esp, %ebp 
    andl $-16, %esp 
    pushl %ebx 
    subl $28, %esp 
    movl $0, %ebx 
    addl $1, %ebx    // because i++ 
    movl $.LC0, %eax 
    movl %ebx, 4(%esp) 
    movl %eax, (%esp) 
    call printf 
    addl $28, %esp 
    popl %ebx 
    movl %ebp, %esp 
    popl %ebp 
    ret  

Można również demontować wykonywalny użyciu objdunp:

$ gcc x.c -o x 
$ objdump x -d 

montażowa Częściowa pomocą polecenia objdump:

080483c4 <main>: 
80483c4: 55      push %ebp 
80483c5: 89 e5     mov %esp,%ebp 
80483c7: 83 e4 f0    and $0xfffffff0,%esp 
80483ca: 53      push %ebx 
80483cb: 83 ec 1c    sub $0x1c,%esp 
80483ce: bb 00 00 00 00   mov $0x0,%ebx 
80483d3: 83 c3 01    add $0x1,%ebx   //due to i++ 
80483d6: b8 b0 84 04 08   mov $0x80484b0,%eax 
80483db: 89 5c 24 04    mov %ebx,0x4(%esp) 
80483df: 89 04 24    mov %eax,(%esp) 
80483e2: e8 0d ff ff ff   call 80482f4 <[email protected]> 
80483e7: 83 c4 1c    add $0x1c,%esp 
80483ea: 5b      pop %ebx 
80483eb: 89 ec     mov %ebp,%esp 
80483ed: 5d      pop %ebp 
80483ee: c3      ret  
80483ef: 90      nop 

%ebx rejestr zarezerwowany dla zmiennej rejestrowej.

6

Nie, nie możesz.

Jest określana przez kompilator i może zmieniać kompilacje, jeśli na przykład otaczający kod zmienia kod register pressure lub jeśli zmieniono flagi kompilatora.

+3

Aby być nieco pedantycznym, pytanie brzmi: jak może je poznać, nie w jaki sposób może to kontrolować. Zgadzam się z Gregiem Hewgillem w jego komentarzu, który można określić na podstawie wyników asemblera. – PeterJ

3

Ja też zgadzam się z odpowiedzią Unwind, z drugiej strony rozmontowanie kodu w GDB może zapewnić przechowywanie zmiennych. Demontaż mgliste kod, który mam daje mieszkańcy tej ramie, jak poniżej,

(gdb) info locals 
i = 0 
ret = <value optimized out> 
k = 0 
ctx = (BN_CTX *) 0x632e1cc8 
A1 = (BIGNUM *) 0x632e1cd0 
A1_odd = (BIGNUM *) 0x632e1ce8 
check = <value optimized out> 
mont = (BN_MONT_CTX *) 0x632e2108 
A = (const BIGNUM *) 0x632e2028 

Teraz jeśli spróbuj wydrukować adres mieszkańców to jednak powiedz mi miejsce przechowywania, jak poniżej,

(gdb) p &i 
$16 = (int *) 0x143fba40 
(gdb) p &k 
$17 = (int *) 0x143fba38 
(gdb) p &mont 
Address requested for identifier "mont" which is in register $s7 
(gdb) 

Tutaj obiekty i i k są na stosie, a mont znajduje się w rejestrze $ s7.

1

Według książki "ANSI C Programming Language - Second Edition" Briana W. Kernighana & Dennis M.Ritchie (założycieli językach C) nie można.

Rozdział 4, Strona 84,

”...I to nie jest możliwe, aby adres zmiennej rejestrowej, niezależnie czy zmienna jest właściwie umieszczony w register.”

nadzieję, że pomoże! Powodzenia w przyszłości, Ron

Powiązane problemy