在8086指令集中使用ASSUME指令

Bal*_*laK 5 assembly emulation x86-16

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

zx4*_*485 10

那么,ASSUME声明是多余的?

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

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

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
Run Code Online (Sandbox Code Playgroud)

data_there segment
  ihavesomevalue dw 1234h
  multiplier     db 02h
  multiplicand   db 08h
  product        dw dup(0)       
data_there ends
Run Code Online (Sandbox Code Playgroud)

这里和之间,assume ds:data_here和之间的区别assume ds:data_there如下:

lea ax, data_here
mov ds, ax
assume  ds:data_here
mov cx, word ptr [multiplier]
Run Code Online (Sandbox Code Playgroud)

导致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]
Run Code Online (Sandbox Code Playgroud)

将导致CX包含1234h - 值ihavesomevalue.

为什么会这样?

嗯,data_here在两种情况下都假设DS .

但在第一种情况,DS指向的假设data_here是正确的,因此变量/数据字节的索引确实适合.

在第二种情况下,DS指向data_there.但汇编程序误导了这个假设,即DS也指向该段data_here.因此变量的索引multiplier是2而不是0,因此在错误的位置访问该值.因此结果不同.

assume指令的不适当应用可能会产生难以检测的错误.

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

BLOCK struct
  item1 dd 0
  item2 dd 0
  item3 dd 0
BLOCK ends
Run Code Online (Sandbox Code Playgroud)

可以通过访问此结构

assume esi:PTR BLOCK 
mov eax, [esi].item2
add ecx, [esi].item3
Run Code Online (Sandbox Code Playgroud)

等等.在上述情况下,ESI被认为/假设为指向BLOCK结构的指针,因此适当地生成索引.

PS:欢迎来到Stack Overflow!