ASSUME在汇编程序中的含义是什么?

时间:2016-12-05 18:55:31

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

无处不在,它被解释为将寄存器与段绑定/关联的东西,但我想理解究竟是什么绑定。

1 个答案:

答案 0 :(得分:5)

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

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

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

  2. 告诉汇编程序有关计算偏移量的段。
    如果在存储器访问中指定段寄存器,汇编器将使用段ASSUME d为该段寄存器计算存储器访问的偏移量。
    请注意,虽然CPU会在每次内存访问时隐式使用DS,但需要使用DS:进行显式覆盖,以明确使用其段作为偏移量的基础。

    < / LI>
  3. ASSUMECS是代码标签所属的细分。
    除非符号位于ASSUME d CS之内,否则您无法跳转/调用符号。

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

    .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__,而不是ASSUME d。