Assembly 为什么要使用临时寄存器将值传递给段寄存器?
我一直在关注编写汇编的几个示例,它们使用临时寄存器将立即数传递给段寄存器。为什么在将立即数放入段寄存器之前需要将其放入某个寄存器中?Assembly 为什么要使用临时寄存器将值传递给段寄存器?,assembly,x86,gnu-assembler,Assembly,X86,Gnu Assembler,我一直在关注编写汇编的几个示例,它们使用临时寄存器将立即数传递给段寄存器。为什么在将立即数放入段寄存器之前需要将其放入某个寄存器中? 示例: movw $0x7c00, %ax movw %ax, %ds ... ... movw $0x6000, %ax movw %ax, %ss 为什么不直接将立即数放入段寄存器中呢 movw $0x7c00, %ds ... movw $0x6000, %ss 因为英特尔没有提供这方面的说明(mov-seg,[ptr],mov-seg,imm16等)。
示例:
movw $0x7c00, %ax
movw %ax, %ds
...
...
movw $0x6000, %ax
movw %ax, %ss
为什么不直接将立即数放入段寄存器中呢
movw $0x7c00, %ds
...
movw $0x6000, %ss
因为英特尔没有提供这方面的说明(
mov-seg,[ptr]
,mov-seg,imm16
等)。所以你必须这么做。结果很好,因为我们不再经常使用段/选择器
但这并不是没有希望。有带段的lea
变体指令,可同时加载段和偏移量:
les di, [someptr]
(这实际上意味着:di=[someptr];es=[someptr+2]
)
您还可以按
/弹出
,以避免寄存器交换,当然要以牺牲内存访问延迟为代价:
push immediate
pop es
许多寄存器仅用于某一目的,对于某些操作不可交换(
bx
用于偏移,cx
用于计数,dx
用于高阶结果,ax
用于结果)。因此,在机器代码文化中,使用临时寄存器并交换它们并不奇怪。这是因为Intel获取或设置段寄存器的唯一指令是:
- 获取寄存器->操作码:8C/r指令:MOV r/m16,Sreg说明:将段寄存器移动到r/m16。
- 设置寄存器->操作码:8E/r指令:MOV Sreg,r/m16说明:将r/m16移动到段寄存器。
MOV DS, AX
# or
MOV DS, WORD PTR [EAX] # or any memory addressing like bellow
MOV DS, WORD PTR [EAX + EBX *2 + 0x456]
.有关汇编指令的压缩信息。不允许立即移动到段寄存器。看,真正的答案是指令集空间很昂贵,因为只有这么多位,而每一条指令都需要晶体管来支持它。因此,CPU设计者不能提供所有可能的有用指令。因此,它们针对常见的活动进行优化(通过提供“方便”的指令),而忽略了支持在代码量或频率方面很少发生的活动的指令。“Mov立即到段”寄存器显然只需使用几条指令即可完成,而且很少需要,所以这就足够了。你应该预料到这一点。