Tho*_*hor 0 x86 assembly intel
我正在研究x86汇编语言,遵循Kip Irvine的书"用于x86处理器的第7版Edi的汇编语言".
在第4章中,作者谈到了机器指令
我的问题是,为什么机器指令中没有al(或表示al)A0 00010400?如果al没有,机器怎么知道我们想要将地址的值移动00010400到al?
============ 编辑1 ===============
我试过mov bl var1并生成了一个机器代码bl
.386
.MODEL FLAT, STDCALL
.STACK 4096
ExitProcess PROTO, dwExitCode: DWORD
.DATA
var1 BYTE 10h
.CODE 
    main PROC 
    MOV BL, var1 
invoke ExitProcess, 0
main ENDP
END main
作为一般规则,寄存器值是存在于机器指令.
然而,x86指令集中存在许多遗留的"包袱".
引入8086时,指令的长度会影响执行时间:更短的指令运行得更快.  
的A寄存器(AX/AL)被称为"累加器"并且使用是在CPU中最通用寄存器.它具有特殊的短版本指令(以前)运行得更快(在原始的8086/8088上).在x86的后续迭代中,其他寄存器被升级为更通用的.现在你几乎可以使用任何寄存器用于所有目的.    
您可以在x86操作码地图上清楚地看到这一点,请参阅:http://sparksandflames.com/files/x86InstructionChart.html
请注意,mov al,[absolute address]有2个编码执行相同的操作:
A0和8A 05
0:  a0 00 00 00 00          mov    al,BYTE PTR ds:0x0
5:  8a 05 00 00 00 00       mov    al,BYTE PTR ds:0x0 
回想起来,这很浪费.但是当时使用累加器寄存器更快地制作指令似乎是个好主意.由于向后兼容,这些错误现在无法纠正.
有可能在新的X64指令集中消除这种重复,但AMD不想做太多改动,所以我们永远坚持这些历史文物.  
我的问题是,为什么机器指令中没有
al(或表示al)A0 00010400?
因为MOV指令(0xA0)的特殊编码始终将AL寄存器作为其目标操作数.其余的代码字节专用于指定源操作数,在本例中是源操作数0x00010400- var1该.DATA部分的地址.
你可以在这张表中看到.您还可以看到有其他特殊编码的指令,像0xA1一个MOV用AX/ EAX作为其目的地操作数,0xA2对于一个版本MOV,其操作数反转(例如,mov var1, al).
这些替代编码存在的原因是在生成的机器代码中保存字节.正如Hans Passant评论的那样,在20世纪70年代中期到x86处理器构思和设计时,这种事情很重要.当时内存非常昂贵,总线速度要慢得多,因此节省空间非常重要 - 即使代价是使处理器的指令解码器更加复杂.鉴于8088上的非常小的(4字节)提取队列,使用这些特殊的单字节指令编码可以显着提高特定代码序列的速度.然而,现在,这个设计在40年后仍在使用,这是英特尔继续遭受的x86平台的一些传统包袱.现代x86芯片必须将不成比例的大部分硅专用于复杂的指令解码器,即使内存非常便宜,因为这些类型的优化并没有真正帮助任何人.
当其中一个操作数是累加器寄存器时,这些特殊编码不仅可用,而且这是特殊编码的最常见情况.
但是,通常情况下,指令使用操作码字节进行编码,然后是每个操作数的字节.这就是你所看到的mov bl, var1.操作码mov reg8, r/m8是0x8A.接下来0x1D将DL寄存器指定为目标操作数.这里有一个方便的操作码表,或者您可以在英特尔的IA-32架构手册中找到每个单独指令的信息.这个网站非常有用,提供"备忘单"作为说明.你可以在Stack Overflow上的x86标签wiki中找到更多这样的链接.
| 归档时间: | 
 | 
| 查看次数: | 100 次 | 
| 最近记录: |