x86 Assembly

Moderators: None (Apply to moderate this forum)
Number of threads: 4563
Number of posts: 16029

This Forum Only
Post New Thread
Single Post View       Linear View       Threaded View      f

Report
A problem with nasm EQU Posted by stranger0 on 29 Dec 2008 at 5:35 AM
So, I decided to begin learning dos 16-bit programming first and then move to protected mode 32-bit assembly when I've got enough experience of 16-bit programming.

I'm using NASM and I'm currently having problem with declaring constants with EQU...

Here is the whole bit of code of my program (if you scroll down, you'll see just the important parts, without all the unnecessary procedures etc):
[BITS 16]

SEGMENT code

..start:

	mov	AX, data
	mov	DS, AX
	mov	AX, stack
	mov	SS, AX
	mov	SP, stacktop

	mov	BL, 00H
M4:
	mov	AL, [Mask]
M3:
	test	BL, AL
	jnz	M1
	mov	DL, [Zero]
	jmp	M2
M1:
	mov	DL, [One]
M2:
	call	DisplayChar

	test	AL, 10H
	jz	M5
	mov	DL, " "
	call	DisplayChar
M5:
	shr	AL, 1
	jnc	M3
	inc	BL
	call	Nwln
	push	200H
	call	Wait
	push	AX
	mov	AH, 06H
	mov	DL, 0FFH
	int	21H
	cmp	AL, 1BH
	je	Prgram_End
	pop	AX
	jmp	M4

Prgram_End:
	mov	AX, 4C00H
	int	21H
	

DisplayChar:
	push	AX
	mov	AH, 02H
	int	21H
	pop	AX
	ret

Nwln:
	push	DX
	push	AX
	mov	DL, 0AH
	mov	AH, 02H
	int	21H
	mov	DL, 0DH
	mov	AH, 02H
	int	21H
	pop	AX
	pop	DX
	ret

Wait:
	push	BP
	mov	BP, SP
	push	BX
	push	CX
	mov	BX, [BP+4]
W1:
	mov	CX, 0FFFFH
W2:
	dec	CX
	jnz	W2
	dec	BX
	jnz	W1
	pop	CX
	pop	BX
	mov	SP, BP
	pop	BP
	ret	2

SEGMENT data

	Mask	equ 80H
	Zero	equ 30H
	One	equ 31H

SEGMENT stack stack

	resb 64
stacktop:


Basically the important parts are here:

	mov	BL, 00H        ; BL works as the counter starting from 00H
M4:
	mov	AL, [Mask]     ; The mask is stored into AL
M3:
	test	BL, AL         ; We test every bit of BL and see if it is
                               ; a 0 or a 1

	jnz	M1             ; if it is one, we display a number 1
                               ; into monitor

	mov	DL, [Zero]     ; if it is zero, we display a number 0
	jmp	M2             ; into monitor
M1:
	mov	DL, [One]
M2:
	call	DisplayChar    ; we display the appropriate number

	test	AL, 10H        ; then we test AL, our mask to see if
                               ; we need to add a space between the
                               ; 4 most significant bits and the 4
                               ; least significant bits

	jz	M5             ; if not, we skip the whole process

	mov	DL, " "        ; else we display a space between them
	call	DisplayChar
M5:
	shr	AL, 1          ; then we shift our mask to test the next
                               ; bit

	jnc	M3             ; this is to check wether we have tested
                               ; all the bits in BL already or not

	inc	BL             ; if we have tested all the bits in BL
                               ; already, we increase BL by one
;...
	jmp	M4             ; and start the testing process from the
                               ; beginning again with a new value in BL


and here:
SEGMENT data

	Mask	equ 80H
	Zero	equ 30H
	One	equ 31H



The code itself is supposed to count from 00H to FFH (in BL register) and display the count in binary numbers, for which it uses mask (stored in AL) to test every single bit in the BL register, and display a 0 (30H ascii) to the monitor if the
test	BL, AL

sets the zero flag to 1,
otherwise it displays a 1 (31H ascii)

now the whole purpouse of the test, apart from learning basic assembly, is to try to work with constants that are declared with EQU. But the problem is, if I use EQU as above in the code, the program displays just a trash in the monitor, but when I change the EQU to db, as in the code below:

        Mask	db 80H
	Zero	db 30H
	One	db 31H


the program works just fine and displays the following into the screen:
0000 0000
0000 0001
0000 0010
0000 0011
0000 0100
0000 0101
... (and so on)

So if I don't use EQU, the program works just fine, but when I use EQU, I get junk. So, now I'm wondering, how on earth can I make the program work with EQU declarations?

(The program itself is taken from an assembly book that uses MASM assembler, so I've had to change the original code in the book quite a bit to get it to work with NASM)

wow, this explanation was too long, I really need to learn to summarise my problems a little bit better.

But if there is anyone who could help me, I would be most thankful for your help!
Report
Re: A problem with nasm EQU Posted by stranger0 on 29 Dec 2008 at 9:14 AM
And while we're on the subject. Is there any decent tutorials, books, source code etc. for learning NASM in DOS 16 bit mode. I've found some pretty neat stuff for NASM under linux and Win-32/64 bit, but so far all my google search results for DOS 16-bit mode NASM has been yealding poor results really. I really want to learn to use NASM in DOS 16 bit mode, if that is a possibility at all!
Report
Re: A problem with nasm EQU Posted by anthrax11 on 29 Dec 2008 at 10:58 AM
equ defines constants that are used during assembly,
db defines actual data in the data section.

Consider these examples:
SomeByte db 0
mov al, [SomeByte]

; if we assume that SomeByte is defined as data for example at
; the address 0x100, then the above code will be assembled as:

0x100: db 0
0x101: mov al, [0x100]

SomeByte equ 0
mov al, [SomeByte]

; here SomeByte is no longer assembled as data, because it is only an
; assembly-time constant, so the code is assembled as simply:

0x100: mov al, [0]

In the last case NASM treats the constant as an address, but of course
the address points to nothing in particular. So basically remove the
square brackets when you use equ and it should work.

If you want to learn to code with NASM under DOS, then there's no need
to look for NASM code specifically. Most assemblers have only few
differences in syntax, it's not that hard to port any asm code to NASM.
Report
Re: A problem with nasm EQU Posted by stranger0 on 29 Dec 2008 at 11:25 AM
: equ defines constants that are used during assembly,
: db defines actual data in the data section.
:
: Consider these examples:
:
: 
: SomeByte db 0
: mov al, [SomeByte]
: 
: ; if we assume that SomeByte is defined as data for example at
: ; the address 0x100, then the above code will be assembled as:
: 
: 0x100: db 0
: 0x101: mov al, [0x100]
: 
:
:
: 
: SomeByte equ 0
: mov al, [SomeByte]
: 
: ; here SomeByte is no longer assembled as data, because it is only an
: ; assembly-time constant, so the code is assembled as simply:
: 
: 0x100: mov al, [0]
: 
:
: In the last case NASM treats the constant as an address, but of
: course
: the address points to nothing in particular. So basically remove the
: square brackets when you use equ and it should work.
:
: If you want to learn to code with NASM under DOS, then there's no
: need
: to look for NASM code specifically. Most assemblers have only few
: differences in syntax, it's not that hard to port any asm code to
: NASM.

Now do I feel stupid; I was going crazy with the program yesterday, and then I find out that it's really a simple problem all in all. But anyway, thank you alot for explaining me that! Everything seems so clear now.

Well, I guess i shouldn't worry that much about porting MASM code into NASM code (it seems to me that the net is full of DOS programs written in MASM...). And thankfully there are forums like this for the occasions when I run into some problems with porting the code.




 

Recent Jobs

Official Programmer's Heaven Blogs
Web Hosting | Browser and Social Games | Gadgets

Popular resources on Programmersheaven.com
Assembly | Basic | C | C# | C++ | Delphi | Flash | Java | JavaScript | Pascal | Perl | PHP | Python | Ruby | Visual Basic
© Copyright 2011 Programmersheaven.com - All rights reserved.
Reproduction in whole or in part, in any form or medium without express written permission is prohibited.
Violators of this policy may be subject to legal action. Please read our Terms Of Use and Privacy Statement for more information.
Operated by CommunityHeaven, a BootstrapLabs company.