【问题标题】:What does ASSUME mean in assembler?ASSUME 在汇编程序中是什么意思?
【发布时间】:2017-04-20 06:19:51
【问题描述】:

到处都将其解释为将寄存器与段绑定/关联的事物,但我想了解确切绑定的内容。

【问题讨论】:

  • 在 NASM 中表示语法错误“错误:解析器:预期指令”。
  • stackoverflow.com/a/39187939/4271923 (它与您的问题并不完全重复,但如果您将阅读这个特定答案与原始问题,它应该大致解释它......为了更准确的定义,您可能已经阅读了TASM 或 MASM 文档)。
  • 我编辑了您的问题以使其更具可读性(在我看来)。随意使用左下角的“编辑”按钮来回滚更改。

标签: assembly x86 tasm 16-bit real-mode


【解决方案1】:

ASSUME 指令告诉汇编器您将使用哪个段寄存器来访问段。

这种“绑定”对于自动化一些常见模式很有用:

  1. 它告诉汇编器使用哪个段寄存器来访问变量。
    如果您在内存访问期间未显式显示段寄存器,则汇编器使用ASSUMEd 值自动将段覆盖前缀添加到指令中。
    如果段没有被任何段寄存器指向ASSUMEd,如果您尝试在该寄存器中加载/存储变量,则汇编器会失败并出现错误。

  2. 它告诉汇编程序要根据哪个段计算偏移量。
    如果您在内存访问中指定段寄存器,则汇编器使用段 ASSUMEd 来计算该段寄存器的内存访问偏移量。
    请注意,尽管 CPU 在每次内存访问时都会隐式使用 DS,但需要使用 DS: 进行显式覆盖,以明确使用其段作为偏移基础的意图。

  3. CS 的段 ASSUMEd 是代码标签所属的段。
    除非符号位于 ASSUMEd 和 CS 之间,否则您不能跳转/调用符号。

考虑下面的程序,它不打算运行,只是反汇编。

.MODEL SMALL
.286

;Segment are laid out sequentially, starting from X and aligned on 16 bytes.
;
;_DATI     X
;_DATI2    X + 10h
;_DATI3    X + 20h
;
;All the variables testX are the first variables in a segment so their
;addresses are the same of their segments

_DATI SEGMENT PARA PUBLIC 'DATA' USE16

   test1 dw 0

_DATI ENDS

_DATI2 SEGMENT PARA PUBLIC 'DATA' USE16

   test2 dw 0

_DATI2 ENDS

_DATI3 SEGMENT PARA PUBLIC 'DATA' USE16

   test3 dw 0

_DATI3 ENDS

_CODE SEGMENT PARA PUBLIC 'CODE' USE16

 ;Use CS to access labels defined inside _CODE and use _CODE to compute those offsets
 ;Use DS to access names defined inside _DATI and use _DATI to compute offsets whenever DS is explicitly used as a segment register
 ;... and so on

 ASSUME CS:_CODE, DS:_DATI, ES:_DATI2

 ;NOTE: _DATI3 NOT ASSUMED!

__START__:

  ;No explicit segment override, find the segment of test1 (_DATI) and use
  ;the assumed register (DS).
  ;Assembled into mov ax, WORD PTR [0000] (A1 00 00)     
  mov ax, WORD PTR [test1]  

  ;No explicit segment override, find the segment of test2 (_DATI2) and use
  ;the assumed register (ES).
  ;Assembled into mov bx, WORD PTR es:[0000] (26 8B 1E 00 00)
  mov bx, WORD PTR [test2]

  ;Explicit segment override, use the segment assumed for ES (_DATI2) to
  ;calculate the offset (0000h).
  ;Assembled as the previous mov cx, WORD PTR es:[0000] (26 8B 0E 00 00)
  mov cx, WORD PTR es:[test2]

  ;Explicit segment override, use the segment assumed for DS (_DATI) to
  ;calculate the offset (0010h).
  ;Assembled as the previous mov dx, WORD PTR es:[0010] (8B 16 10 00)
  mov dx, WORD PTR ds:[test2]

  ;OFFSET of X is always relative to the segment X is declared in. 
  ;This is true for MASM mode only, IDEAL mode use the group

  ;Both use an offset of 0, as both test1 and test2 are the first variables
  ;of their segments
  mov ax, OFFSET test1              ;mov ax, 0000  (B8 00 00)
  mov bx, OFFSET test2              ;mov bx, 0000  (BB 00 00)

  ;No explicit segment override, find the segment of test3 (_DATI3) and
  ;use the assumed register (none)
  ;Can't assemly: error -> Can't address with currently ASSUMEd segment registers
  mov ax, WORD PTR [test3]  

  ;Explicit segment override, calculate offset of test3 with respect of the
  ;segment assumed for DS (_DATI)
  ;Offset is 20h
  mov bx, WORD PTR ds:[test3]       ;mov bx, WORD PTR [0020] (8B 1E 20 00)

  ;OFFSET operator don't use assumed register
  mov cx, OFFSET test3
_CODE ENDS

END __START__

如果你不这样做 ASSUME CS 汇编程序会抱怨

当前段无法访问 CS

因为您在代码段中定义标签 __START__ 而不是 ASSUMEd 任何地方。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-04-18
    • 1970-01-01
    • 2011-02-02
    • 2011-12-19
    • 1970-01-01
    • 1970-01-01
    • 2011-09-11
    • 1970-01-01
    相关资源
    最近更新 更多