我们是否能够使用汇编(x86)语言中的 MOV 指令以这些方式将内存操作数移动到段寄存器?
1.
MOV DS,[BX]
2.
MOV DS,[6401H]
是的,英特尔支持mov ds, reg/mem
,但不支持mov ds, imm16
。
验证1) gcc -c foo.s; objdump -d foo.o
mov (%bx), %ds
mov 1231(%bx), %ds
d: 67 8e 1f mov (%bx),%ds
10: 67 8e 9f cf 04 mov 0x4cf(%bx),%ds
验证2)会比较棘手,因为 PE 386 中的指令在 gcc/cygwin 中转换为
mov 0x7b, %reg
; 但它适用于任何寄存器。在 80286 OTOH 中,有一种寻址模式mov [0x1111], reg
。
mov (123), %ds // the target is protected mode 386
mov (123), %bx
15: 8e 1d 7b 00 00 00 mov 0x7b,%ds
1b: 66 8b 1d 7b 00 00 00 mov 0x7b,%bx
paulsm4 关于问题 2) 可能是正确的——虽然例如 Flat Assembler 能够mov ax,[123]
在 8086 模式下编译,但它不允许mov ds,[123]
.
但是,如果您允许对规则进行一些弯曲,例如,如果 bx/bp/[sp]/di/si 中的任何一个为零,则mov ds, [1234 + reg]
允许。
是的,两种寻址模式都有效。
您已将这个问题标记为 Masm 和 Nasm。他们不一样,你知道的!为了说服 Masm 你想要一个内存引用,你可能需要做mov ds, ds:[6401h]
- 奇怪,我知道,但那是汇编器的语法 - 或者是,我最后一次使用 Masm(很久以前!)。冗余ds:
在 Masm 中被优化掉,Nasm 会发出它。如果 Fasm 不这样做,那么 Fasm 就坏了(我对此表示怀疑!Tomasz 是个天才!)...... 用 Fasm 尝试一下 - 效果很好!
顺便说一句,32 位地址确实涉及一个段寄存器 - 操作系统设置了它们,并且很少在“用户空间”代码中使用它们,但它们仍然存在!(64 位代码,不,但我不太确定)。
伙计——本世纪甚至没有人使用 DS 寄存器 :)!
我强烈建议您学习 32 位汇编程序。如果您可以访问 Linux,这是一个极好的资源:
回答你的问题 - 我相信“不”。您通常从 AX 寄存器加载 DS(尽管您当然可以使用其他三个通用寄存器中的任何一个)。
绝对确定,您应该在 Intel 参考手册中查找它(您应该可以在 Google 上找到它)。
PS:
当我说“32 位”时,我赶紧补充一点,你为 x86-32 学到的任何东西都直接适用于 x86-64。但是,您为 16 位 DOS 学习的大部分(大部分?)内容不适用于任何当代(阅读:虚拟内存/线性地址空间)系统。
恕我直言...