作者回复: 这又是一个好问题!其实这里我们在代码中使用的是 AT&T 的写法,是一种默认被编译器广泛支持的内联汇编写法。当然,我们也可以做适当的调整来使用 Intel 写法,比如这样: #include <stdio.h> int main(void) { register long num asm("rax") = 0x100000000; asm( ".intel_syntax noprefix \n\t" "mov eax, 1\n\t" // "mov ax, 1\n\t" ".att_syntax" ); printf("%ld\n", num); return 0; } 但这种方式的问题在于,对于某些汇编器可能没有很好的兼容性。
作者回复: 完全正确!
作者回复: 很好的问题! 第一个问题:每一个汇编指令都有其对应的组成结构,汇编器会根据助记符的名称进行相应的转换。具体的转换细节可以参考官方手册。比如对于 x86-64:https://www.intel.com/content/www/us/en/developer/articles/technical/intel-sdm.html 第二个问题:二进制状态下的机器指令识别可以通过每个指令对应的 OpCode 字节进行切分,然后再根据相应的结构解析出整体指令的结构。
作者回复: 答案是正确的哈!
作者回复: 这是一个很好的发现!我们修改了文章,稍后会更新。 简单来讲就是:字这个概念会在多个地方的多种不同场景下使用。而文中我们介绍的字实际上是指可以体现 CPU 硬件特征的那个字,我一般会称它为硬件字。而在 CPU 指令集中,字也被用来作为衡量数据大小的单位。x86 架构由于历史原因,会将指令集中出现的 WORD 定义为固定 16 位的大小。所以实际文中提到的 4 个字你可以理解为指令字,它的单位是 WORD,4 个字即对应 64 位大小。
作者回复: 关于这个问题我可以先给点提示,然后你再思考下看看。第一个提示就是把第一行 printf 中的 “%d” 改成 “%ld” 就可以输出正确的结果;第二个提示是 printf 的调用会影响寄存器 rax 的值。
作者回复: 没错!
作者回复: 理解正确哈!
作者回复: 正解!
作者回复: 这是一个很好的发现!