【问题标题】:moving memory operand to segment register,assembly(x86)将内存操作数移动到段寄存器,程序集(x86)
【发布时间】:2012-11-05 21:41:10
【问题描述】:

我们是否能够使用汇编(x86)语言中的 MOV 指令以这些方式将内存操作数移动到段寄存器?

1.

MOV DS,[BX]

2.

MOV DS,[6401H]

【问题讨论】:

    标签: assembly x86 nasm intel masm


    【解决方案1】:

    是的,两种寻址模式都有效。

    您已将此问题标记为 Masm 和 Nasm。他们不一样,你知道的!为了说服 Masm 你想要一个内存引用,你可能需要做mov ds, ds:[6401h] - 奇怪,我知道,但那是汇编器的语法 - 或者是,我最后一次使用 Masm(很久以前!)。多余的ds: 在 Masm 中被优化掉,Nasm 会发出它。如果 Fasm 不这样做,那么 Fasm 就坏了(我对此表示怀疑!Tomasz 是个天才!)...刚刚用 Fasm 试了一下 - 效果很好!

    顺便说一句,32 位地址确实涉及段寄存器 - 操作系统设置了它们,并且很少在“用户空间”代码中使用它们,但它们仍然存在! (64 位代码,不,但我不太确定)。

    【讨论】:

    • 我也检查过:./FASM.EXE bar.asm 平面汇编程序版本 1.70(1484627 千字节内存) bar.asm [1]: mov ds, ds:[6401h] 错误:操作数无效。
    • Fasm 和 Nasm 一样,希望在括号内覆盖段。试试mov ds, [ds:6401h]ds: 是多余的 - 与 Masm 类似,但与 Nasm 不同,Fasm 将其删除)。
    • 我似乎不明白... objdump -Mi8086 将此解码为mov 0x6401,%ds,这是不受支持的。
    • AT&T 语法希望 "$" 指示立即操作数。 mov 0x6401, %ds 是该地址的内存。 mov $0x6401, %ds 将不受支持。一定会喜欢那个 AT&T! :)
    【解决方案2】:

    是的,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
    

    paulsm4 关于问题 2) 可能是正确的——而例如Flat Assembler 能够在 8086 模式下编译 mov ax,[123],它不允许 mov ds,[123]

    但是,如果您允许对规则进行一些弯曲,例如如果 bx/bp/[sp]/di/si 中的任何一个为零,则允许 mov ds, [1234 + reg]

    【讨论】:

    • 实际上,您引用的参考资料并未说明这是否恰好适用于 DS。我不是 100% 确定,但我认为不是。
    【解决方案3】:

    老兄——本世纪甚至没有人使用 DS 寄存器 :)!

    我强烈建议您学习 32 位汇编程序。如果您可以访问 Linux,这是一个很好的资源:

    回答您的问题 - 我相信“不”。您通常从 AX 寄存器加载 DS(尽管您当然可以使用其他三个通用寄存器中的任何一个)。

    绝对确定,您应该在英特尔参考手册中查找它(您应该可以在 Google 上找到它)。

    PS:

    当我说“32 位”时,我赶紧补充一点,你为 x86-32 学到的任何东西都直接适用于 x86-64。但是,您为 16 位 DOS 学习的大部分(大部分?)内容适用于任何当代(阅读:虚拟内存/线性地址空间)系统。

    恕我直言...

    【讨论】:

    • 请注意,FSGS 仍用于线程本地存储和访问内核结构等用途(参见 SWAPGS 指令)。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-02-05
    相关资源
    最近更新 更多