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