[英]Where are pointers when we disassemble with gdb
當我通過以下代碼在gdb中使用disas
命令時:
int main(){
char*a;
size_t r;
return 1;
}
我有這個結果:
0x080483db <+0>: push %ebp
0x080483dc <+1>: mov %esp,%ebp
0x080483de <+3>: mov $0x1,%eax
0x080483e3 <+8>: pop %ebp
0x080483e4 <+9>: ret
我不明白為什么沒有關於char*a
和size*t
。 我如何獲得的ADRESS a
值, r
值? 它們甚至存在嗎?
聲明char*a;
和size_t r;
不要自己做任何事情 ; 他們寧願告訴編譯器,您希望能夠使用標識符a
和r
來存儲值,並且其生存期僅限於main
執行的持續時間。 另一方面,大多數匯編說明(nops等除外) 都可以執行某些操作 。
如果您在這些變量中存儲和訪問了值,或者獲取了它們的地址並使用了這些地址,而這在某種意義上並不等同於不做任何事情,那么您會看到編譯器發出了騰出空間的代碼(通常是通過調整堆棧來實現)指針,或將某些寄存器推入堆棧以保存其值,以便為數據提供額外的空閑寄存器)並存儲/加載值。
您需要進行實驗,以使無效代碼不會得到優化。
unsigned int fun0 ( void )
{
return(0x12345678);
}
char * fun1 ( void )
{
char *x;
x = (char *)0x12345678;
return(x);
}
unsigned int fun2 ( unsigned int x )
{
return(x+12);
}
unsigned int * fun3 ( unsigned int *x )
{
return(x+3);
}
給這樣的東西
Disassembly of section .text:
00000000 <fun0>:
0: e59f0000 ldr r0, [pc] ; 8 <fun0+0x8>
4: e12fff1e bx lr
8: 12345678 eorsne r5, r4, #120, 12 ; 0x7800000
0000000c <fun1>:
c: e59f0000 ldr r0, [pc] ; 14 <fun1+0x8>
10: e12fff1e bx lr
14: 12345678 eorsne r5, r4, #120, 12 ; 0x7800000
00000018 <fun2>:
18: e280000c add r0, r0, #12
1c: e12fff1e bx lr
00000020 <fun3>:
20: e280000c add r0, r0, #12
24: e12fff1e bx lr
這里要注意的是C語言有一個as-if規則 ,該規則說編譯后的程序只需要產生相同的可觀察行為 。
由於您的程序的可觀察行為等同於
int main(){
return 1;
}
那就是編譯后的代碼所做的。
這並不僅僅適用於聲明,並且可以任意復雜。 例如常見的hello world程序:
#include <stdio.h>
int main(){
printf("Hello world!\n");
}
具有與
#include <stdio.h>
int main(){
puts("Hello world!");
}
如果使用-O3
編譯前者,則得到后一個程序:
.LC0:
.string "Hello world!"
main:
leaq .LC0(%rip), %rdi
subq $8, %rsp
call puts@PLT
xorl %eax, %eax
addq $8, %rsp
ret
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.