【问题标题】:Assembly 8086 EQU directive汇编 8086 EKU 指令
【发布时间】:2016-10-31 16:26:07
【问题描述】:

我无法在汇编程序 (8086) 中明确 EQU 指令。

abc EQU xyz

当在代码中找到带有 xyz、xyz 代表的任何值、值等时,EQU 是否会从字面上交换 abc?

即我可以写吗?

varA EQU [bp+4]

mov ax, varA

还有一个问题是 EQU 可以全局访问,即我可以在程序外定义 EQU,并在程序内使用它吗?

【问题讨论】:

  • 取决于您使用的实际汇编程序。是emu8086吗?那我就不知道了。但是大多数 x86 汇编器没有预处理器。因此,这种情况下的 EQU 是根据定义进行评估的,而不是替换的。我有 99% 的把握,这也是你的情况。对于预处理器,可以随意运行一些 C 编译器预处理器(甚至是独立的,但我总是有 gcc,所以我会选择 C ​​的)。
  • 嗯,我明白了。汇编中有什么类似预处理器的东西,我真的需要它吗?
  • 刚刚编辑了我的答案以证明 EQU 是全局的(在过程中声明了 EQU)。

标签: assembly x86-16 emu8086


【解决方案1】:

EQU 项目不是变量,它们不占用任何内存空间:

  • EQU 引用一个常量值时,它成为该值的同义词。此值无法被覆盖,即使您尝试它也不会改变。
  • EQU 引用另一个变量时,它会成为该变量的同义词,因此发生在同义词上的所有事情都会发生在变量上。

在 EMU8086 中复制粘贴下一个代码并运行:

.model small
.stack 100h
.data

xyz DW  2016    ;◄■■■ ABC IS NOT A VARIABLE, IT IS
abc EQU xyz     ;     JUST A SYNONYM FOR XYZ.

pqr EQU 10      ;◄■■■ PQR IS NOT A VARIABLE, IT IS
                ;     JUST A SNYNONYM FOR NUMBER 10.

varA EQU [bp+2] ;◄■■■ BP POINTS TO GARBAGE.

.code

mov  ax, @data
mov  ds, ax

mov  abc, 25    ;◄■■■ XYZ BECOMES 25!!!!

mov  pqr, 999   ;◄■■■ NO ERROR, BUT THE VALUE WILL NOT CHANGE.
mov  ax, pqr    ;◄■■■ AX IS NOT 999, AX=10.

mov  si, varA   ;◄■■■ GARBAGE.
mov  bp, sp
mov  si, varA   ;◄■■■ DIFFERENT GARBAGE.
push ax         ;◄■■■ PUSH 10.
call my_proc

mov  ax, NUMBER ;◄■■■ YES, EQUS ARE GLOBAL!!! (AX=0B9H).

mov  ax, 4c00h
int  21h

;-----------------------------------------

my_proc proc  
mov  bp, sp
mov  si, varA    ;◄■■■ WRONG VALUE (ANOTHER GARBAGE). 
mov  si, [bp+2]  ;◄■■■ PROPER VALUE (10).

varB EQU [bp+2]
mov  si, varB    ;◄■■■ WRONG AGAIN.

NUMBER EQU 0b9h  ;◄■■■ DEFINE EQU INSIDE PROCEDURE.

ret
my_proc endp          

[bp+2] 的情况下,它似乎不起作用,可能是因为编译器无法获得固定值。

【讨论】:

  • 使用varA EQU [bp+2]varB EQU [bp+2] 产生的垃圾清楚地表明EMU8086 甚至不应该首先接受这些等式。发现模拟器中的另一个缺陷! +1 很高兴看到您花时间了解 EQU。
  • mov pqr, 999 ;◄■■■ 没有错误,但值不会改变。 我不敢相信我的眼睛 EMU8086 接受这个!这个模拟器的怪癖列表将在哪里结束?
【解决方案2】:

EQU 简单地表示相等,因此abc EQU xyz, xyz 必须事先定义。

在你的第二个例子中,它需要像

%define varA [bp+4]

mov   ax, varA

然后在你的代码被组装之后,一个对象转储就会产生

移动斧头,[bp+4]

然后你可以做类似的事情

Bubble equ varA

mov  bx, Bubble

你会得到

mov bx, [bp+4]

一般来说,所有的汇编程序都以相同的方式工作,尽管在语法上存在细微差别,例如 NASM 需要 %,其他的可能不会。

【讨论】:

    【解决方案3】:

    一些汇编器有合理的宏支持,通常在内部作为预处理器工作,或者非常接近它。

    否则正如我在评论中所写的,你为什么不使用 C 预处理器? (它是独立的工具,你可以用它预处理任何文本文件,只需使用#define和其他扩展你的asm源,其余内容不必看起来像C源,预处理器不在乎,它正在处理文件作为 [any] 文本文件)。

    你需要吗?我不会。我在 ASM 中编写了大量代码只是因为我缺乏经验,而且宏/预处理器不会让我摆脱那个巨大的错误(它们可能只会让它变得不那么明显,并且在更长的时间内更容易忍受)。

    虽然您出于教育原因或性能/低级别的事情在 ASM 中只执行一小段代码,但宏/预处理器恕我直言会添加抽象层来隐藏生成的指令,因此在调试期间您可能会发现自己在问“在哪里这个是从哪里来的?”。我更喜欢手动编写每条 ASM 指令,知道我为什么把它放在那里,我不希望在 ASM 代码中出现任何意外,在 ASM 中编写无错误代码已经相当困难了。

    然后,我在 ASM 中的大部分后期工作都是 256B 介绍,所以我真的必须知道产生的每个字节...... :)

    【讨论】:

    • 我敢打赌,你是编写那些只有 256 字节的 Apple ][ 扩展卡 ROM 的人。它们的内存太紧了,我看到一些代码分支到另一条指令的中间以获得副作用。它是另一个分支指令的偏移量0x38,后跟RTS0x38 恰好是指令 SEC 并且厚颜无耻的小伙子在那里分支以获得带有进位集的 RTS
    • @WeatherVane 我必须谦虚地承认我从来没有走到那一步......自我修改代码?查看。将代码本身也用作处理数据?查看。但是部分重用的操作码......不记得做过那个。这是有趣的轶事,泰。 :)(我从来没有做过 Apple ][,只有 ZX Spectrum)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-06-25
    • 1970-01-01
    • 2022-11-25
    • 2018-04-28
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多