Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/http/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Assembly 8086内存到内存指令。他们存在的目的是什么?_Assembly_X86_Intel_X86 16 - Fatal编程技术网

Assembly 8086内存到内存指令。他们存在的目的是什么?

Assembly 8086内存到内存指令。他们存在的目的是什么?,assembly,x86,intel,x86-16,Assembly,X86,Intel,X86 16,据我所知,8086指令有3种关于数据移动的指令集: 要注册的内存 寄存器到内存 登记 然而,昨天我发现了一些指令集,如and, 在使用这些指令时,内存对内存(M2M)操作是可能的 现在,我很好奇为什么会有M2M指令存在。 我发现使用它们有很多限制 这些指令消耗大量CPU周期 这些指令要求使用段寄存器作为操作数。 这些M2M操作也可以通过组合上述1、2、3种指令来运行 问题: 我很难同意这些M2M指令的存在。 这些是否仅用于生成较短的装配代码 movs*和cmps*指令非常方便,因为它们允许

据我所知,8086指令有3种关于数据移动的指令集:

  • 要注册的内存
  • 寄存器到内存
  • 登记
  • 然而,昨天我发现了一些指令集,如and,
    在使用这些指令时,内存对内存(M2M)操作是可能的

    现在,我很好奇为什么会有M2M指令存在。
    我发现使用它们有很多限制

    • 这些指令消耗大量CPU周期
    • 这些指令要求使用段寄存器作为操作数。

    这些M2M操作也可以通过组合上述1、2、3种指令来运行

    问题:
    我很难同意这些M2M指令的存在。

    这些是否仅用于生成较短的装配代码

    movs*和cmps*指令非常方便,因为它们允许您执行复制数据和比较数据等常见任务

    ins*
    out*
    本质上类似于
    mov*
    ,它们只是在内存和I/O设备之间移动数据。它们对于在完整扇区(通常为512字节)中读取/写入磁盘特别有用。当然,DMA消除了这些,因为基于DMA的I/O效率更高,但在当时,它们并不像今天那样普遍

    模拟这些指令(特别是它们的重复形式(查找
    rep
    prefix))需要更多的代码,速度也会更慢。因此他们的存在

    顺便说一句,目标在内存中的
    xchg
    指令和任何其他读-修改-写指令(例如
    add
    )也是有效的内存对内存指令。并非所有CPU都有这些功能,许多CPU主要提供从内存读取或写入内存的指令,但并非两者都有(例外情况是用于实现对内存的独占/原子访问的指令,比如
    xchg
    xadd
    cmpxchg8/16
    )。具有此类指令集的CPU属于所谓的负载存储体系结构

    另外,
    push
    pop
    指令可能会让它们的显式操作数指定内存位置。这是另一种形式的内存对内存指令


    至于段,几乎所有读取或写入内存的指令都涉及段(某些系统指令的工作方式不同),因此,如果您决定不使用您提到的指令,而选择其他指令,则段管理和开销不是您可以避免的。

    架构师已经论证,一些常见的高级功能可以在硬件中得到支持。因此,
    movsb
    可以实现
    memcpy
    和friends,
    outsb
    在对缺少足够辅助硬件的哑设备执行IO时非常有用(这在过去是常见的情况)。当然,这不是一个原创的想法或东西-在RISC运动出现之前,这种指令在任何地方都很常见(除了非常小的8位“micro”)。注意:只有8088/8086有内存移动,早期PC时代的8237 DMA芯片包括内存到内存的传输功能,使用频道0作为源,频道1作为目标。@rcgldr哦,哇,我不知道。有人真的用过这个功能吗?@fuz-我没用过。我似乎记得它在我工作的一家公司进行测试,可能是在20世纪80年代对各种台式机上的dma内存移动和/或cpu内存移动进行基准测试,以了解内存带宽。所有内存操作数都有一个段寄存器,无论是显式指定的还是隐式的。相关:列出具有两个独立内存操作数的指令,不是同一操作数的RMW。少数加载存储ISA也有原子交换(例如)和/或CA,但大多数RISC ISA只支持so
    lock add
    转换为重试循环。(仅compare_exchange_weak不需要循环,因为它允许在争用时失败,而不仅仅是数据差异)。LL/SC在中断延迟方面具有优势,因为它基本上使原子事务可中止。您可以(在一个位置上)实现任何原子操作,但也可以对CAS重试循环执行相同的操作。LL/SC确实可以更容易地避免ABA问题。。。不管怎么说,别谈这个话题了。LL/SC仍然是两条单独的指令,每一条指令只加载或只存储。但是它们链接在一起作为RMW事务提交,因此它们解决了与8086
    xchg
    或更高版本的x86
    lock-cmpxchg
    /
    lock-add
    /
    lock-xadd
    /etc相同的问题,使同时处理2个段变得容易,而不会使用段覆盖前缀使代码膨胀。代码大小对8086的性能至关重要。