如何知道寄存器变量存储在哪里?

我知道寄存器变量存储在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) 

对象ik在堆栈上, mont在寄存器$ s7中。

根据Brian W. Kernighan和Dennis M.Ritchie(C语言的创始人)的书“The Ansi C Programming Language – Second Edition”, 你不能

第4章,第84页,

“……无论变量是否实际放在寄存器中,都无法获取寄存器变量的地址。”

希望有所帮助! 祝你好运,将来,罗恩