NASM - The Netwide Assembler
NASM Forum => Programming with NASM => Topic started by: tysonprogrammer 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.
; 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
(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
-
Try the following:
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.
-
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:
nasm -f bin myprog.asm -o myprog.com
No linker required.
To print the errorlevel/exitcode:
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:
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
-
Hello, this should work:
[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
-
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.
-
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
-
It occurs to me that "cd" (hex obviously) is the opcode for "int". Could that be what you're seeing, Tyson?
Best,
Frank
-
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:
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 (http://ctyme.com/intr/int.htm).
And debs3759 is right. You need to adjust DS.
-
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.
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.
[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
-
Sorry fellas it seems I have been having issues posting.
Setting the data segment/section seems to have fix the issue.
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
-
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