assembly - TASM 初始化局部变量
问题描述
我是汇编语言的新手,我正在使用 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 chess3.asm, chess3.obj, chess3.lst
给出列表文件chess33.lst
:
1 0000 .model small
2 0000 .stack 0100h
3 0000 .data
4
5 0000 .code
6 0000 _MAIN PROC
7 0000 B8 0000s MOV AX, @DATA
8 0003 8E D8 MOV DS, AX
9
10 LOCAL a[12]: BYTE
11 ; my solution to initializing the a[12] local variable
12 0005 C6 46 F4 68 MOV a[0], 'h'
13 0009 C6 46 F5 61 MOV a[1], 'a'
14 000D C6 46 F6 6E MOV a[2], 'n'
15 0011 C6 46 F7 6C MOV a[3], 'l'
16 0015 C6 46 F8 6F MOV a[4], 'o'
17 0019 C6 46 F9 24 MOV a[5], '$'
18
19 001D 8D 56 F4 LEA DX, [a] ; for some reason "MOV DX, OFFSET a" doesn't output "hanlo" in dosbox (i guess+
20 it points to a different address? I'm not sure how tho)
21 0020 B4 09 MOV AH, 09h
22 0022 CD 21 INT 21h
23
24 ; EXIT
25 0024 B4 4C MOV AH, 4Ch
26 0026 CD 21 INT 21h
27 0028 _MAIN ENDP
28
29 END _MAIN
MOV a[0],'h'
汇编到的指令C6 46 F4 68
实际上是伪装的MOV BYTE [BP-12+0],'h'
,因为它是在 asm-timeLOCAL a[12]: BYTE
定义的 TASM 方式。a
BP-12
LEA DX,[a]
组装为LEA DX,[BP-12]
. 这就是MOV DX,OFFSET a
不汇编的原因:MOV DX,OFFSET BP-12
是无效指令。
还要注意 DOS 函数http://www.ctyme.com/intr/rb-2562.htm:它需要字符串地址,DS:DX
但本地堆栈变量的默认段寄存器BP
是SS
(而不是DS
)。幸运的是,在您的程序中DS=SS
,但在非小内存模型中并非总是如此。
推荐阅读
- docker - 如何删除(已删除)docker-container的docker-volume?
- azure - 从不同订阅的另一个 azure 容器存储库 (ACR) 引用 docker 映像
- pandas - 使用多索引列连接两个 pandas 数据框
- google-play-console-beta - 从 Google Play 控制台下载 APK(测试版)
- java - 如何在 Java 的 get 和 return 方法中使用 input(int)?
- regex - 创建正则表达式模式以排除字符串
- python - qt应用程序和外部软件之间的2种python通信方式
- bash - 相同的脚本在手动获得正确结果的 cron 上给出结果为零
- wordpress - 如何在我的 WordPress 网站中使用自定义 SMTP 设置
- python - 如何在范围(n)中具有整数键的字典和长度为 n 的列表之间进行选择?