8086指令集中ASSUME指令的使用

the use of ASSUME directive in 8086 instruction set

在我的教科书中,假定 ASSUME 指令告诉汇编程序要用作物理段的逻辑段的名称。并且它使用从指定逻辑段开始的位移来编写指令。 Click here for the screenshot. 但是,当我在 emu8086 中执行这个汇编程序时,它会自动确定 offsets/displacements (即使在注释掉 ASSUME 语句之后)。它是如何做到的?那么,ASSUME 语句是多余的吗?

So, ASSUME statement is redundant?

没有。 ASSUME 指令告诉 assembler 假设 ,某个寄存器包含某个结构的基础(在您的情况下:段)。在您的情况下,CS 和 DS 分别指向 代码段 数据段 ,它们都是各自同类中的唯一一个。所以CS是已经假定作为指向代码段的指针,因为代码段是唯一的。 DS也是。

例如,如果您将 mov ax, 2000h ; mov ds, ax 的 DS 更改为假设的第二个 数据段 位于(段)地址 2000h,一些对内容的引用可以被误导。 以下代码片段不正确,不会 assemble,它们的唯一目的是说明差异

data_here segment
  multiplier     db 02h
  multiplicand   db 08h
  product        dw dup(0)       ; ??? btw, missing a count between dw and dup(0) ?
data_here ends

data_there segment
  ihavesomevalue dw 1234h
  multiplier     db 02h
  multiplicand   db 08h
  product        dw dup(0)       
data_there ends

这里和那里,assume ds:data_hereassume ds:data_there 的区别如下:

lea ax, data_here
mov ds, ax
assume  ds:data_here
mov cx, word ptr [multiplier]

导致 CX 包含 0802h(乘数 + LSB 顺序的被乘数)。现在将 DS 指向 data_there 并假设 data_here:

lea ax, data_there       ; MODIFIED !!!
mov ds, ax
assume  ds:data_here
mov cx, word ptr [multiplier]

会导致 CX 包含 1234h - ihavesomevalue 的值。

为什么会这样?

好吧,在这两种情况下,DS 都被假定为 data_here

但在第一种情况下,假设,即 DS 指向 data_here 是正确的,因此 variables/data 字节的索引确实适合。

在第二种情况下,DS 指向 data_there。但是 assembler mis 导致 假设 ,即 DS 也指向段 data_here。所以变量 multiplier 的索引是 2 而不是 0,因此在错误的地方访问了值。因此结果不同。

assume 指令的不当应用会产生难以检测的错误。

顺便说一句,assume 指令可用于方便目的,例如泛化对寄存器中结构的访问,这将增加代码的可读性:

BLOCK struct
  item1 dd 0
  item2 dd 0
  item3 dd 0
BLOCK ends

此结构可以通过

访问
assume esi:PTR BLOCK 
mov eax, [esi].item2
add ecx, [esi].item3

等等。在上述情况下,ESI considered/assumed 是指向 BLOCK 结构的指针,因此会适当生成索引。

P.S.: 欢迎来到 Stack Overflow!