Search code examples
assemblyx86-16tasmemu8086dosbox

TASM Initializing Local Variables


I'm new in Assembly Language and I'm programming using TASM in DOSBOX x86-16

I've looked everywhere in the internet for a TASM way of initializing a local variable and found none.
Actually my first problem before that was figuring out how to make a local variable in TASM.
After not finding one for TASM specifically, I tried the one for MASM and just tried it in TASM and surprisingly it worked!

Now the only problem is I can't find a way to initialize that local variable. I worked out a naive solution, here's my code:

.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

Questions

1. How do you initialize this local variable? Is there a way where I can do something similar to initializing a variable in the .data segment? like this:
.model small
.stack 0100h
.data
    inputPrompt db "Enter your name: $" ; can i do something like this, but inside the .code segment?
.code
...
  1. As you can see in the second comment of my code MOV DX, OFFSET a, for some reason, doesn't point at the start of the a local variable. I changed it to LEA DX, [a] then it suddenly worked. Here's the output for both codes:

    LEA DX, [a]
    LEA OUTPUT

    MOV DX, OFFSET a
    MOV OUTPUT

    What do you think is going on here exactly?

  2. I also try my TASM codes in EMU8086 because I can clearly see the registers being set and it's just a really good program for learning assembly in general. But for some reason, when I try this exact code, it gives an error in EMU8086 when executed, specifically when using the LOCAL directive (most likely because EMU8086 uses a different syntax).

    Everything works fine except when I use the LOCAL directive. Here's the error: enter image description here What's the correct syntax to declare and initialize a local variable in EMU8086?

Lastly if you guys know a very nice x86-16 TASM DOSBOX assembly tutorial please do share, something that explains what this and that register do exactly (something that perfectly explains the fundamentals I guess)


Solution

  • TASM chess3.asm, chess3.obj, chess3.lst gives the listing file 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
    

    Instruction MOV a[0],'h' assembled to C6 46 F4 68 is in fact disguised MOV BYTE [BP-12+0],'h' because LOCAL a[12]: BYTE is TASM way to define a as BP-12 at asm-time.

    LEA DX,[a] is assembled as LEA DX,[BP-12]. This is the reason why MOV DX,OFFSET a doesn't assemble: MOV DX,OFFSET BP-12 is invalid instruction.

    Also pay attention to DOS function http://www.ctyme.com/intr/rb-2562.htm : it expects the string address in DS:DX but the default segment register of local stack variables addressed with BP is SS (and not DS). Luckily in your program DS=SS but this isn't always the case in non-small memory models.