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_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
是正确的,因此 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!
在我的教科书中,假定 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_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
是正确的,因此 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!