【发布时间】:2021-03-17 12:01:13
【问题描述】:
我是汇编语言新手,我正在使用 DOSBOX x86-16 中的 TASM 进行编程
我在互联网上到处寻找初始化局部变量的 TASM 方法,但没有找到。
实际上,在那之前我的第一个问题是弄清楚如何在 TASM 中创建一个局部变量。
在没有找到一个专门用于 TASM 的之后,我尝试了一个用于 MASM 的,然后在 TASM 中尝试了它,令人惊讶的是它起作用了!
现在唯一的问题是我找不到初始化该局部变量的方法。 我想出了一个天真的解决方案,这是我的代码:
.model small
.stack 0100h
.data
.code
_MAIN PROC
MOV AX, @DATA
MOV DS, AX
LOCAL a[12]: BYTE
; my solution to initializing the a[12] local variable
MOV a[0], 'h'
MOV a[1], 'a'
MOV a[2], 'n'
MOV a[3], 'l'
MOV a[4], 'o'
MOV a[5], '$'
LEA DX, [a] ; for some reason "MOV DX, OFFSET a" doesn't output "hanlo" in dosbox (i guess it points to a different address? I'm not sure how tho)
MOV AH, 09h
INT 21h
; EXIT
MOV AH, 4Ch
INT 21h
_MAIN ENDP
END _MAIN
问题
1.如何初始化这个局部变量?有没有办法可以做类似于初始化 .data 段中的变量的事情?像这样:.model small
.stack 0100h
.data
inputPrompt db "Enter your name: $" ; can i do something like this, but inside the .code segment?
.code
...
-
正如您在我的代码
MOV DX, OFFSET a的第二条注释中看到的那样,由于某种原因,它没有指向a局部变量的开头。我将其更改为LEA DX, [a]然后它突然起作用了。这是两个代码的输出:LEA DX, [a]MOV DX, OFFSET a
您认为这里到底发生了什么? -
我还在 EMU8086 中尝试了我的 TASM 代码,因为我可以清楚地看到正在设置的寄存器,而且它只是一个非常好的学习汇编的程序。但是由于某种原因,当我尝试这个确切的代码时,它在执行时会在 EMU8086 中出现错误,特别是在使用 LOCAL 指令时(很可能是因为 EMU8086 使用了不同的语法)。
一切正常,除非我使用 LOCAL 指令。这是错误: 在 EMU8086 中声明和初始化局部变量的正确语法是什么?
最后,如果你们知道一个非常好的 x86-16 TASM DOSBOX 汇编教程,请分享,它解释了这个和那个寄存器的确切作用(我猜这完美地解释了基本原理)
【问题讨论】:
-
TASM 和 EMU8086 是不同的汇编程序。它们对实际指令和一些基本指令使用相同的语法,但是像
local指令这样的额外奇怪的东西显然是 TASM 独有的。通常,您只需使用sub sp, 12或其他方式手动执行此操作。在 asm 中使用复杂的“高级”功能通常会破坏学习 asm 的目的;我建议您仅在熟悉 asm 并知道如何查看反汇编输出以查看 TASM 为这些指令生成的实际指令后才检查这些功能。 -
OFFSET不是运行时运算符。像OFFSET a这样的表达式的值是在汇编或链接时计算的。但是使用局部变量是不可能的,因为这样的变量在你进入函数时在堆栈上分配,然后在你离开函数时释放。 -
我明白了,谢谢伙计们,我会阅读更多关于堆栈的信息,我实际上是在将函数帧保存在堆栈中之前通过将它们推入堆栈来保存所有寄存器先前状态的内容当函数结束时,它将通过将其弹出来恢复先前的状态,但在不同的上下文中。如果你们知道任何很好的 16 位 asm 教程可以很好地解释这些概念,请分享。
标签: assembly x86-16 tasm emu8086 dosbox