我们是否能够使用汇编(x86)语言中的MOV指令以这些方式将内存操作数移动到段寄存器?
1
MOV DS,[BX]
2
MOV DS,[6401H]
答案 0 :(得分:1)
是的,Intel支持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
对于问题2),paulsm4可能是正确的 - 例如Flat Assembler能够在8086模式下编译mov ax,[123]
,它不允许mov ds,[123]
。
但是,如果您允许对规则进行一些修改,例如如果bx / bp / [sp] / di / si中的任何一个为零,则允许mov ds, [1234 + reg]
。
答案 1 :(得分:1)
是的,两种寻址模式都有效。
你有这个问题标记为Masm和Nasm。他们不一样,你知道!为了说服Masm你需要一个内存引用,你可能需要做mov ds, ds:[6401h]
- 奇怪,我知道,但这是汇编程序的语法 - 或者是,我最后一次使用Masm(很久以前!)。多余的ds:
在Masm中得到优化,Nasm会发射它。如果Fasm不会这样做,那么Fasm就会被打破(我对此表示怀疑!Tomasz是个天才!)......只是用Fasm试了一下 - 工作得很好!
顺便提一下,32位地址确实涉及一个段寄存器 - 操作系统设置了它们,很少在“userland”代码中使用'em',但它们仍然存在! (64位代码,没有 - 但我不太确定)。
答案 2 :(得分:0)
老兄 - 本世纪没有人使用DS注册:)!
我强烈建议您学习32位汇编程序。如果您可以访问Linux,这是一个很好的资源:
回答你的问题 - 我相信“不”。您通常从AX寄存器加载DS(尽管您当然可以使用其他三个通用寄存器)。
绝对确定,您应该在英特尔参考手册中查找(您应该可以在Google上找到它)。
PS:
当我说“32位”时,我赶紧补充说,你学习x86-32的任何内容都直接适用于x86-64。但是你学习16位DOS的东西(大多数?)不适用于任何现代(读取:虚拟内存/线性地址空间)系统。
... IMHO