假设我在 C 编译器生成的目标文件上运行#grid {
display: grid;
}
.big {
grid-template-columns: repeat(3 1fr);
grid-template-rows: auto;
grid-template-areas:
"header header header"
"misc misc misc"
[* * *] <---- unknown rows
"footer footer footer";
}
.small {
grid-template-columns: 1fr;
grid-template-rows: auto;
grid-template-areas:
"header"
"misc"
[*] <---- unknown rows
"footer";
}
,我得到了这个反汇编:
objdump -d
我不确定如何解释这里的一切。走线:
0000000000400b5e <main>:
400b5e: 55 push %rbp
400b5f: 48 89 e5 mov %rsp,%rbp
400b62: bf 50 0a 49 00 mov $0x490a50,%edi
400b67: e8 04 0b 00 00 callq 401670 <_IO_puts>
400b6c: 5d pop %rbp
400b6d: c3 retq
400b6e: 66 90 xchg %ax,%ax
我得到400b62: bf 50 0a 49 00 mov $0x490a50,%edi
语句正在做什么,但mov
是什么意思? 400b62
是什么意思?我在互联网上找不到任何解释如何阅读这些内容的内容。
答案 0 :(得分:4)
400b62
是指令的地址。 bf 50 0a 49 00
是组成指令的字节。在这种情况下,400b62
处的指令将寄存器%edi
设置为0x490a50。这里bf
表示“设置edi”,50 0a 49 00
是0x490a50的字节,以小端顺序排列(如英特尔处理器那样)。
如果您希望能够读取每条指令,则需要进行一些解码,但可以完成。我的经验中最好的参考是Intel® 64 and IA-32 Architectures Software Developer Manuals,但它们不适合胆小的人。
答案 1 :(得分:2)
从汇编语言入门开始,例如https://speakerdeck.com/vsergeev/x86-assembly-primer-for-c-programmers,如果你已经知道C,那就很好。
在您的代码中,重要的是
mov $0x490a50,%edi
callq 401670 <_IO_puts>
x86-64的前6个参数通过寄存器传递
rdi, rsi, rdx, rcx r8, r9
。 (edi
是rdi
)的一半,所以这会将一个参数传递给一个待调用的函数,然后调用该函数。
解码后的名称(_IO_puts
)表明您正在处理puts
的实现,这意味着0x490a50
是传递给字符串的内存地址的十六进制表示形式它
原始主要可能是:
#include <stdio.h>
int main() { puts("hello world"); }