在询问了relation between assembly and machine code之后,我开始阅读Intel 64 instruction set reference。
这里还有很多需要学习的地方,但是在看完前两章(需要更多地学习第2章)之后,我还没有更深入地理解机器代码的含义。也许在阅读了所有1300多页的内容,以及组装艺术,也许还有一门CS架构课程之后,这门课程在实践中的应用将开始有意义。
但同时,你能解释一下为什么编译汇编文件中的数字(或者我猜是“二进制”)是由8个列的4个十六进制数组成的一个网格吗?这对你来说可能是显而易见的,但我不知道这是否意味着什么。
cffa edfe 0700 0001 0300 0000 0100 0000
0200 0000 0001 0000 0000 0000 0000 0000
1900 0000 e800 0000 0000 0000 0000 0000
0000 0000 0000 0000 0000 0000 0000 0000
2e00 0000 0000 0000 2001 0000 0000 0000
2e00 0000 0000 0000 0700 0000 0700 0000
0200 0000 0000 0000 5f5f 7465 7874 0000
0000 0000 0000 0000 5f5f 5445 5854 0000
0000 0000 0000 0000 0000 0000 0000 0000
2000 0000 0000 0000 2001 0000 0000 0000
5001 0000 0100 0000 0005 0080 0000 0000
0000 0000 0000 0000 5f5f 6461 7461 0000
0000 0000 0000 0000 5f5f 4441 5441 0000
0000 0000 0000 0000 2000 0000 0000 0000
0e00 0000 0000 0000 4001 0000 0000 0000
0000 0000 0000 0000 0000 0000 0000 0000
0000 0000 0000 0000 0200 0000 1800 0000
5801 0000 0400 0000 9801 0000 1c00 0000
e800 0000 00b8 0400 0002 bf01 0000 0048
be00 0000 0000 0000 00ba 0e00 0000 0f05
4865 6c6c 6f2c 2077 6f72 6c64 210a 0000
1100 0000 0100 000e 0700 0000 0e01 0000
0500 0000 0000 0000 0d00 0000 0e02 0000
2000 0000 0000 0000 1500 0000 0200 0000
0e00 0000 0000 0000 0100 0000 0f01 0000
0000 0000 0000 0000 0073 7461 7274 0077
7269 7465 006d 6573 7361 6765 006c 656e
6774 6800
更具体地说。。。
正如selected answer中关于程序集和机器代码之间关系的另一个问题所指出的,所有信息至少都在英特尔文档中的某个地方。例如,在第二章开头,他们会说:
锁前缀使用F0H编码。
REPNE/REPNZ前缀使用F2H编码。。。
锁前缀(F0H)强制执行一个操作,该操作确保在多处理器环境中独占使用共享内存。。。
重复前缀(F2H,F3H)导致对字符串的每个元素重复指令。。。
我知道,通过
F0H
,它们实际上是指“f0
这是一个十六进制数,如果不清楚”。所以你可以在上面的机器代码中找到这个数字几次。例如,在第6列的底部附近是bf01
。在不了解更多的情况下,我试图将非常具体(但不太实际)的英特尔文档与一些实际的机器代码组合在一起,这样我就可以真正“了解”英特尔文档是如何实际应用的。
作为理解过程的第一步,我想知道:
f0
中的bf01
是否与英特尔文档中描述的相同?也就是说,它是锁前缀吗?如果不是,你怎么知道?为什么数字在一个8列4个数字的网格中?
如果
F0H
块中的f0
表示锁前缀,为什么它从奇数位置开始(即,它不是从偶数位置开始,如列中的0或2位置)?这是整个问题的主要原因。如果它可以出现在一个奇数位置,那么将它们分成8列,每列4个数字,每个数字都是任意的(也就是说,让它看起来很漂亮),因为如果所有的操作码都至少有2个字符,那么它永远不会出现在奇数位置。 最佳答案
为什么数字在一个8列4个数字的网格中?
这就是你或者你正在使用的工具选择显示它们的方式。我个人会显示单个字节,而不是两个字节的单词。我会根据如何显示或打印十六进制转储来选择列数。
研究机器代码十六进制转储的最佳方法是使用反汇编程序。有一个在线的here。例如,它反汇编以下十六进制转储
55 31 D2 89 E5 8B 45 08 56 8B 75 0C 53 8D 58 FF
0F B6 0C 16 88 4C 13 01 83 C2 01 84 C9 75 F1 5B
5E 5D C3
到
.data:0x00000000 55 push ebp
.data:0x00000001 31d2 xor edx,edx
.data:0x00000003 89e5 mov ebp,esp
.data:0x00000005 8b4508 mov eax,DWORD PTR [ebp+0x8]
.data:0x00000008 56 push esi
.data:0x00000009 8b750c mov esi,DWORD PTR [ebp+0xc]
.data:0x0000000c 53 push ebx
.data:0x0000000d 8d58ff lea ebx,[eax-0x1]
.data:0x00000010
.data:0x00000010 loc_00000010:
┏▶ .data:0x00000010 0fb60c16 movzx ecx,BYTE PTR [esi+edx*1]
┃ .data:0x00000014 884c1301 mov BYTE PTR [ebx+edx*1+0x1],cl
┃ .data:0x00000018 83c201 add edx,0x1
┃ .data:0x0000001b 84c9 test cl,cl
┗ .data:0x0000001d 75f1 jne loc_00000010
.data:0x0000001f 5b pop ebx
.data:0x00000020 5e pop esi
.data:0x00000021 5d pop ebp