TASM 初始化局部变量

TASM Initializing Local Variables

我是汇编语言的新手,我正在 DOSBOX x86-16 中使用 TASM 编程

我在互联网上到处寻找初始化局部变量的 TASM 方法并找到 none。
实际上,在那之前我的第一个问题是弄清楚如何在 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
...
  1. 正如您在我的代码 MOV DX, OFFSET a 的第二条注释中看到的那样,出于某种原因,它没有指向 a 局部变量的开头。我将其更改为 LEA DX, [a] 然后它突然起作用了。这是两个代码的输出:

    LEA DX, [a]


    MOV DX, OFFSET a


    你认为这里到底发生了什么?

  2. 我也在 E​​MU8086 中尝试了我的 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' assembled 到 C6 46 F4 68 实际上是伪装的 MOV BYTE [BP-12+0],'h' 因为 LOCAL a[12]: BYTE 是 TASM 将 a 定义为 BP-12 在 asm-time.

LEA DX,[a] 是 assembled 为 LEA DX,[BP-12]。这就是为什么MOV DX,OFFSET a不assemble的原因:MOV DX,OFFSET BP-12是无效指令。

还要注意DOS函数http://www.ctyme.com/intr/rb-2562.htm:它需要DS:DX中的字符串地址,但是用BP寻址的局部堆栈变量的默认段寄存器是SS (而不是 DS)。幸运的是,在您的程序中 DS=SS 但在非小内存模型中情况并非总是如此。