在8086指令集中使用ASSUME指令

时间:2016-02-07 08:40:51

标签: assembly emulation x86-16

在我的教科书中,它给出了ASSUME指令告诉汇编器用作物理段的逻辑段的名称。并且它使用从指定逻辑段的开头的位移来编码指令。  RFC 823 但是,这里当我在emu8086中执行这个汇编程序时,它会自动确定偏移/位移(即使在注释掉ASSUME语句之后)。它是如何做到的?那么,ASSUME语句是多余的?

1 个答案:

答案 0 :(得分:10)

  

那么,ASSUME语句是多余的?

没有。 ASSUME指令告诉汇编程序假设,某个寄存器包含某些结构的基础(在您的情况下:segment)。在您的情况下,CS和DS分别指向代码段数据段,它们分别是各自的一种。因此,CS 已被假定为作为指向代码段的指针,因为代码段是唯一的代码段。 DS也是如此。

如果您要将mov ax, 2000h ; mov ds, ax的DS更改为位于(段)地址2000h的假设的第二个数据段,则对该内容的某些引用可能会被误导。 以下代码段不正确且无法组装,其唯一目的是说明差异

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是正确的,因此变量/数据字节的索引确实适合。

在第二种情况下,DS指向data_there。但汇编程序 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被认为/假设是指向BLOCK结构的指针,因此索引是适当生成的。

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