标题来自于这个帖子
里面举了个例子 Understanding static local variables by assembly
或许这才是第三章的重点所在?
-
Understanding C by learning assembly
-
@诟屍 我看这个意图甚明显。
-
(gdb) break main Breakpoint 1 at 0x100000f9d: file simple.c, line 3. (gdb) run Starting program: /Users/lbwang/SourceCode/C/simple Unable to find Mach task port for process-id 17930: (os/kern) failure (0x5). (please check gdb is codesigned - see taskgated(8)) (gdb)
我这样运行竟然出错,就是照着帖子跑的。这个gdb出了什么问题?
-
@ping1008 我对Clang这种运行方式也表示非常不解:
$ CFLAGS="-g -O0" make simple cc -g -O0 simple.c -o simple
有没有相关简明教程?
-
@bintou 在 Understanding C by learning assembly 中说:
(gdb) break main Breakpoint 1 at 0x100000f9d: file simple.c, line 3. (gdb) run Starting program: /Users/lbwang/SourceCode/C/simple Unable to find Mach task port for process-id 17930: (os/kern) failure (0x5). (please check gdb is codesigned - see taskgated(8)) (gdb)
我这样运行竟然出错,就是照着帖子跑的。这个gdb出了什么问题?
-
@诟屍 唉。。。long story。。。程序员的日常。暂时不搞了。
顺便。。。论坛支持快捷键吗?
-
macOS中,gdb会出现莫名的unknown signal错误。(有的人说是bug,有的人说是certificate错误,不特别理解)
所以我的写法是,clang --std=gnu99 -g astry.c -o simple lldb ./simple
假设源代码为:
#include <stdio.h> int main(int argc, char *argv[]) { int a = 5; int b = a + 6; return 0; }
那么,在lldb下:
lldb ./simple ## 得到: (lldb) target create "./simple" Current executable set to './simple' (x86_64). (lldb) ## 然后: (lldb) l ## 得到: 3 int main(int argc, char *argv[]) { 4 int a = 5; 5 int b = a + 6; 6 return 0; 7 } (lldb) b 3 Breakpoint 1: where = simple`main + 20 at astry.c:4, address = 0x0000000100000fa4 (lldb) r Process 62110 launched: './simple' (x86_64) Process 62110 stopped * thread #1, queue = 'com.apple.main-thread', stop reason = breakpoint 1.1 frame #0: 0x0000000100000fa4 simple`main(argc=1, argv=0x00007fff5fbff9d8) at astry.c:4 1 #include <stdio.h> 2 3 int main(int argc, char *argv[]) { -> 4 int a = 5; 5 int b = a + 6; 6 return 0; 7 } ………………一直enter,可以看到每一步。当然,更多细节还是不特别了解。
-
@bintou 在 Understanding C by learning assembly 中说:
顺便。。。论坛支持快捷键吗?
试过装这个插件,默认的快捷键会和浏览器自带快捷键产生冲突,又懒得自定义,于是卸了
-
lldb很多地方很坑。比如,next是按thread走的。。。
## GDB 的结果: simple`main: 0x100000f90 <+0>: pushq %rbp 0x100000f91 <+1>: movq %rsp, %rbp 0x100000f94 <+4>: xorl %eax, %eax 0x100000f96 <+6>: movl
$0x0, -0x4(%rbp) 0x100000f9d <+13>: movl %edi, -0x8(%rbp) 0x100000fa0 <+16>: movq %rsi, -0x10(%rbp) 0x100000fa4 <+20>: movl $0x5, -0x14(%rbp) 0x100000fab <+27>: movl -0x14(%rbp), %edi 0x100000fae <+30>: addl $0x6, %edi 0x100000fb1 <+33>: movl %edi, -0x18(%rbp) -> 0x100000fb4 <+36>: popq %rbp 0x100000fb5 <+37>: retq ##clang的: simple`main: 0x100000f90 <+0>: pushq %rbp 0x100000f91 <+1>: movq %rsp, %rbp 0x100000f94 <+4>: xorl %eax, %eax 0x100000f96 <+6>: movl $0x0, -0x4(%rbp) 0x100000f9d <+13>: movl %edi, -0x8(%rbp) 0x100000fa0 <+16>: movq %rsi, -0x10(%rbp) 0x100000fa4 <+20>: movl $0x5, -0x14(%rbp) 0x100000fab <+27>: movl -0x14(%rbp), %edi 0x100000fae <+30>: addl $0x6, %edi 0x100000fb1 <+33>: movl %edi, -0x18(%rbp) -> 0x100000fb4 <+36>: popq %rbp 0x100000fb5 <+37>: retq 好像没有区别。在
-O0
的时候。 -
@诟屍 跟这帖子跑不行,各种方式都试过。不知道原因。特此记录。
-
这里有点小意思。我重复了该链接下的代码的实验,得到了两种不同的汇编代码。区别在于,第一种,变量b的地址比a的要“小”(downward),而我得出的却是相反(upward)。还有,按帖子说地址
-0x4(%rbp)
是一种“clang的隐藏变量”,好神秘!结论,clang与gcc的差别不小。或者,谁能告诉我更多细节?
Simple代码
int main() { int a = 5; int b = a + 6; return 0; }
原文给出的汇编代码(Mac OS,Clang)
(gdb) disassemble Dump of assembler code for function main: 0x0000000100000f50 <main+0>: push %rbp 0x0000000100000f51 <main+1>: mov %rsp,%rbp 0x0000000100000f54 <main+4>: mov
$0x0,%eax 0x0000000100000f59 <main+9>: movl $0x0,-0x4(%rbp) 0x0000000100000f60 <main+16>: movl $0x5,-0x8(%rbp) 0x0000000100000f67 <main+23>: mov -0x8(%rbp),%ecx 0x0000000100000f6a <main+26>: add $0x6,%ecx 0x0000000100000f70 <main+32>: mov %ecx,-0xc(%rbp) 0x0000000100000f73 <main+35>: pop %rbp 0x0000000100000f74 <main+36>: retq End of assembler dump. b的地址在
-0xc(%rbp)
我得到的汇编代码(Ubuntu下,gcc)
(gdb) disassemble Dump of assembler code for function main: 0x00000000004004d6 <+0>: push %rbp 0x00000000004004d7 <+1>: mov %rsp,%rbp 0x00000000004004da <+4>: movl
$0x5,-0x8(%rbp) 0x00000000004004e1 <+11>: mov -0x8(%rbp),%eax 0x00000000004004e4 <+14>: add $0x6,%eax 0x00000000004004e7 <+17>: mov %eax,-0x4(%rbp) 0x00000000004004ea <+20>: mov $0x0,%eax 0x00000000004004ef <+25>: pop %rbp 0x00000000004004f0 <+26>: retq End of assembler dump. b的地址在
-0x4(%rbp)
-
The C standard says nothing about the order in which local variables are allocated. It doesn't even use the word "stack". It only requires that local variables have a lifetime that begins on entry to the nearest enclosing block (basically when execution reaches the {) and ends on exit from that block (reaching the }), and that each object has a unique address. It does acknowledge that two unrelated variables might happen to be adjacent in memory (for obscure technical reasons involving pointer arithmetic), but doesn't say when this might happen.
The order in which variables are allocated is entirely up to the whim of the compiler.
If you need to variables to be allocated in a particular order, you can wrap them in an array or a structure.至于 clang 的神秘变量,我也不清楚,看起来又不像 canary