Author Topic: Variable isn't what I expected.  (Read 8650 times)

Offline tysonprogrammer

  • Jr. Member
  • *
  • Posts: 22
  • Country: us
  • C# application developer attempting assembly.
Variable isn't what I expected.
« on: September 21, 2020, 12:03:27 AM »
I a newish to assembly and nasm. Iw as reading a book on masm assembly to learn assembly and so I thought I had a good handle on addressing, guess not. Anyway I wrote this little program that is supposed add two numbers to see if I could figure it out.

Code: [Select]
; add.a

bits 16 ; tell nasm how many bits we are using

segment data
    val1    db 10h
    val2    db 20h

segment code
..start:
    xor al, al                  ; zero out al
    mov al, [val1]
;    add al, [val2]

exit:
        mov ah, 4ch     ;exit
        int 21h         ;call intr

segment stack class=stack
        resb 512 ; 64 is a little to little for interrupts


When I run this program through a debugger I am not seeing the value for val1, and I am so confused. I am using the Open Watcom debugger. Like to screenshot is below. Instead of 10h I am seeing CD as the value.


https://www.dropbox.com/s/ag87rirnue5z7pe/Screen%20Shot%202020-09-20%20at%207.46.30%20PM.png?dl=0


I am using nasm on FreeDOS running in VirtualBOX.

any help would be appreciated.

thanks,
Tyson

Offline debs3759

  • Global Moderator
  • Full Member
  • *****
  • Posts: 221
  • Country: gb
    • GPUZoo
Re: Variable isn't what I expected.
« Reply #1 on: September 21, 2020, 01:03:25 AM »
Try the following:

Code: [Select]
bits 16

section .data                  ; I always use section in nasm, can't remember if segment is handled the same
                                      ; Data section is named .data for nasm
                                      ; In your code, presumably because of section/segment names, data is placed before the code section.
        val1    db 10h

section .text                  ; nasm calls the code section .text
org 100h                       ; needed if creating a .com binary
;..start                           ; nasm doesn't need this line for a DOS binary

        mov dx,cs
        mov ds,dx               ; set data segment to be the same as code segment for .com files
                                       ; without this, the data will be loaded from the wrong area of memory
        xor al,al
        mov al,[val1]

exit:
        mov ah,4ch
        int 21h

As you are not using the stack, you don't need to set it up. If you do start using it, you need to explicitly set it up. I can't remember whether the manual explains how to do this, but in most DOS .com executable, it can be the same as CS as well, then will need a cld instruction.

All this is from memory, so if it doesn't work for you I will check the basics. It should be right though, and om program exit, AL should still contain the last value placed in it, as a return code.
« Last Edit: September 21, 2020, 01:10:57 AM by debs3759 »
My graphics card database: www.gpuzoo.com

Offline Frank Kotler

  • NASM Developer
  • Hero Member
  • *****
  • Posts: 2667
  • Country: us
Re: Variable isn't what I expected.
« Reply #2 on: September 21, 2020, 02:38:32 AM »
Hi Tyson,
Welcome to the forum.

This is embarrassing. My memory is all shot.

"..start" is a special symbol known only to "-f obj". If that's what you're using, it won't like ''org'' as Debs suggests. You will want the stack. To do as Debs suggests:
Code: [Select]
nasm -f bin myprog.asm -o myprog.com
No linker required.
To print the errorlevel/exitcode:
Code: [Select]
echo %errorlevel%
I'm not sure about the % signs. (Told you this was embarrassing.)

I can't vouch for your debugger and I'm confused by your screenshot, I see "10" (doesn't say that it's hex, but probably is) I don't see "cd". Your code looks good to me. So I'm confused!

What I would do is do the addition. 30h is ascii code for '0' (the character, not the number 0). Print it:
Code: [Select]
mov ah, 0eh
int 10h
That should put "0" on your screen.

If none of that helps, get back to us and make us do it!
This is embarrassing.

Best,
Frank






Offline avcaballero

  • Full Member
  • **
  • Posts: 132
  • Country: es
    • Abre los Ojos al Ensamblador
Re: Variable isn't what I expected.
« Reply #3 on: September 21, 2020, 08:53:47 PM »
Hello, this should work:
Code: [Select]
[org 100h]
[section .text]
  inicio:
  MOV   AH, 0Eh
  MOV   AL, 9                 ; byte you want to print
  OR    AL, 30h
  INT   10h
  RET
Compile with:
>nasm -fbin Program.asm -o Program.com
« Last Edit: September 21, 2020, 08:55:35 PM by avcaballero »

Offline debs3759

  • Global Moderator
  • Full Member
  • *****
  • Posts: 221
  • Country: gb
    • GPUZoo
Re: Variable isn't what I expected.
« Reply #4 on: September 21, 2020, 09:18:31 PM »
I can't vouch for your debugger and I'm confused by your screenshot, I see "10" (doesn't say that it's hex, but probably is) I don't see "cd". Your code looks good to me. So I'm confused!

Biggest problem I see is that he didn't set up DS, so it's not pointing at his data segment.
My graphics card database: www.gpuzoo.com

Offline Frank Kotler

  • NASM Developer
  • Hero Member
  • *****
  • Posts: 2667
  • Country: us
Re: Variable isn't what I expected.
« Reply #5 on: September 21, 2020, 09:38:39 PM »
Thanks Debs, Thanks Alfonso,

I think DOS will set ds for either a .com file, as both of you suggest or an MZ file (as "..start" suggests. I could be wrong.

Best,
Frank


Offline Frank Kotler

  • NASM Developer
  • Hero Member
  • *****
  • Posts: 2667
  • Country: us
Re: Variable isn't what I expected.
« Reply #6 on: September 21, 2020, 10:51:00 PM »
It occurs to me that "cd" (hex obviously) is the opcode for "int". Could that be what you're seeing, Tyson?

Best,
Frank

« Last Edit: September 21, 2020, 10:57:11 PM by Frank Kotler »

Offline fredericopissarra

  • Full Member
  • **
  • Posts: 368
  • Country: br
Re: Variable isn't what I expected.
« Reply #7 on: September 22, 2020, 12:11:22 AM »
Where are you testing this? DOSBox?

The service 0x0e from INT 0x10 requires:
AL = character.
BH = page number
BL = attribute

So, to print a green '0' you'll need to do:
Code: [Select]
  mov ah,0x0e
  mov al,'0'
  mov bx,0x0002  ; BH=0 (page 0), BL=0b00000010
                 ; BL = ibgrIBGR (i and I, intensity bit,
                 ;                r and R, red bit,
                 ;                g and G, green bit,
                 ;                b and B, blue bit ).
                 ; Uppercase is foreground. lowercase, background.
  int 0x10

Here's the Ralf Brown's Interrupt List.

And debs3759 is right. You need to adjust DS.
« Last Edit: September 22, 2020, 12:34:50 AM by fredericopissarra »

Offline avcaballero

  • Full Member
  • **
  • Posts: 132
  • Country: es
    • Abre los Ojos al Ensamblador
Re: Variable isn't what I expected.
« Reply #8 on: September 22, 2020, 03:40:44 AM »
As Debs points out, the problem is that he has defined an EXE-DOS structure, which needs to set up the different segments, otherwise anything could be happen.
Code: (exe) [Select]
SEGMENT datos1 data
  val1  DB   3
SEGMENT datos2 data
  val2  DB   7
SEGMENT Pila STACK              ; Stack segment
  RESB  256                     ; 256 bytes
InicioPila:

SEGMENT code
..start:                        ; Informamos que aquí empieza el código
  MOV   AX, Pila                ; Setting up the stack
  MOV   SS, AX
  MOV   SP, InicioPila

  MOV   AX, datos1              ; Setting up DS
  MOV   DS, AX
  MOV   AH, 0Eh
  mov   AL, [val1]               ; byte you want to print
  OR    AL, 30h
  INT   10h

  MOV   AX, datos2              ; Setting up DS
  MOV   DS, AX
  MOV   AH, 0Eh
  mov   AL, [val2]               ; byte you want to print
  OR    AL, 30h
  INT   10h

  MOV   AH, 4ch
  INT   21h                     ; Salimos AL DOS
compile with:
>nasmw -fobj Program.asm
>link with your favourite linker


While COM-DOS structure doesn't need to set up the differents segments because all are the same, everything lies in the same segment.
Code: (COM) [Select]
[org 100h]
[section .text]
  MOV   AH, 0Eh
 
  mov   AL, [var1]             ; byte you want to print
  OR    AL, 30h
  INT   10h
 
  mov   AL, [var2]             ; byte you want to print
  OR    AL, 30h
  INT   10h
 
  RET
[section .data]
  var1  db 3
  var2  db 7
compile with:
> nasmw -fbin Program.asm -o Program.com

Offline tysonprogrammer

  • Jr. Member
  • *
  • Posts: 22
  • Country: us
  • C# application developer attempting assembly.
Re: Variable isn't what I expected.
« Reply #9 on: September 23, 2020, 10:36:08 PM »
Sorry fellas it seems I have been having issues posting.

Setting the data segment/section seems to have fix the issue.

Code: [Select]

mov ax data
mov ds, ax


I am compiling on FreeDOS 2.1 running in a VirtualBox 6.1  VM

I have a batch file which runs the following

nasm -w+orphan-labels -F borland -fobj -o %1.o %1.a

%1 being the file I am compiling.

I then use the following command to link it
wlink name %1.exe format dos file %1.o

this is the Open Watcom linker

If there is a easier way to compile to an exe without a linker I would appreciate a hint :)

thanks,
Tyson
« Last Edit: September 23, 2020, 11:04:16 PM by tysonprogrammer »

Offline Frank Kotler

  • NASM Developer
  • Hero Member
  • *****
  • Posts: 2667
  • Country: us
Re: Variable isn't what I expected.
« Reply #10 on: September 24, 2020, 01:34:34 AM »
Hi Tyson,

Yes. avcaballero's  two examples above show both methods. Assembling  directly to a ".com" file is  easier(?)... but is probably not what is shown in your book. nasm -f bin prog.asm -o prog.com

An .exe file is what you've been doing. We do need to set ds. I remembered incorrectly.
nasm -f obj prog.asm
wlink prog.obj

In either case, your variables look okay to me.
mov al, [var1] : contents of variable = 10h
mov ax, var1 : address (offset) of variable
Nasm does not use the word "offset".

Best,
Frank