如何知道寄存器变量存储在哪里?
我知道寄存器变量存储在CPU寄存器中。
如果CPU寄存器忙/满,则相同的变量存储在堆栈中。
我怎么知道变量存储在堆栈或CPU寄存器中?
我同意Unwind先生的回答 ,但在某种程度上,这种方式可能对您有所帮助:
文件名xc
:
int main(){ register int i=0; i++; printf("%d",i); }
汇编代码:
~$ gcc xc -S
输出文件名是xs
。
在我的情况下,使用ebx
寄存器, 这可能在不同的编译时间有所不同。
~$ cat xs .file "xc" .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
您还可以使用objdunp
反汇编您的可执行文件 :
$ gcc xc -ox $ objdump x -d
使用objdump
命令输出部分程序集:
080483c4 : 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 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
寄存器保留用于寄存器变量。
不,你不能。
它由编译器决定,并且可能在编译之间发生变化,例如,如果周围的代码改变了寄存器压力或者编译器标志被更改了。
我也同意UnWind的答案,另一方面,在GDB中反汇编代码可能会给存储变量。 我拆开了一个模糊的代码,给出了该框架的当地人,如下所示,
(gdb) info locals i = 0 ret = k = 0 ctx = (BN_CTX *) 0x632e1cc8 A1 = (BIGNUM *) 0x632e1cd0 A1_odd = (BIGNUM *) 0x632e1ce8 check = mont = (BN_MONT_CTX *) 0x632e2108 A = (const BIGNUM *) 0x632e2028
现在,如果尝试打印当地人的地址,它会告诉我存储位置如下,
(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)
对象i
和k
在堆栈上, mont
在寄存器$ s7中。
根据Brian W. Kernighan和Dennis M.Ritchie(C语言的创始人)的书“The Ansi C Programming Language – Second Edition”, 你不能 。
第4章,第84页,
“……无论变量是否实际放在寄存器中,都无法获取寄存器变量的地址。”
希望有所帮助! 祝你好运,将来,罗恩