Page 1 of 1

Macros givin me grief [SOLVED]

Posted: Sat Jun 07, 2008 5:14 pm
by tadada
I was thinking about my print functions which I have been working on when I thought about macros. I thought about it a little more and realised with macros some one could create a mean print function for example.

So I go to try it. I convert my clear screen function (which works) into a macro and compile. Nothing happens but my "h" is written. This comes after the clear screen. The macro didn't through an error. It just skipped it. I convert it back and it worked again.

So I was wondering if the problem is obvious (like some option I must pass to nasm at compile time) or is something more subtle.

I have seen someone use a macro to do a realmode print function.

Thanks in advance

BTW: I compiled my SCRN functions alone into a file (SYS file). (just them, the clear screen and my beginnings of a putch function both of which were macros.) The file came out as being empty. (0 bytes) I loaded it with Notepad++ and it was empty.

My clear screen code:

Code: Select all

%macro clrscrn 0
	pusha
	mov		ebx, 0x18
	mov		es, ebx
	mov		ebx, 0
	mov		al, " "
	mov		ah, 8Fh
%%loopscrn:
	mov		word [es: ebx], ax
	inc		ebx
	inc		ebx
	cmp		ebx, 0xFA0
	jne 	%%loopscrn
	mov		ebx, 0
	popa
	ret
%endmacro

Posted: Sat Jun 07, 2008 5:40 pm
by suthers
Nothing coming out when you assemble a macro, I think thats normal, I think the assembler doesn't assemble it if its not called...
My OS used to be called SOS to BTW, but it stood for something else...
Jules

Posted: Sat Jun 07, 2008 6:51 pm
by tadada
Is the proper way to call a macro to just type its name on a line

example of what I think is the correct way:

Code: Select all


start:
   foo

%macro foo 0
   mov   eax, 0x18
   mov   es, eax
%endmacro
EDIT: I have the NASM manual open to the macro section but it isn't too clear on how to call macros, especially ones with no parmeters.

Posted: Sat Jun 07, 2008 6:56 pm
by Dex
suthers is right, when you call a macro the code is placed where the call was made, so if you call it 20 times, your program will be bigger by 20 times the size of the macro.

A proc is differant, as its a jmp with a return address, so if you call a proc 20 times it will only be bigger by the call instructions *20 and once the size of the proc code

So if you do not call it your program will not be any bigger.
[edit]
in fasm you use macro like this

Code: Select all

macro PRINT String{

        local .Printer
        local .Nextchar
        local .Done
        local .a

        .Printer:
                mov si, .a
                mov ah, 0Eh
                jmp .Nextchar

        .Nextchar:
                lodsb
                or al, al
                jz .Done
                int 10h
                jmp .Nextchar
                jmp .Done

        .a db String,10,13,0

        .Done:
}  

macro SCREEN mode
{
	push ax

	if mode = 0
		mov ah,0h		;SCREEN 0; Default DOS screen mode
		mov al,3h
		int 10h
	else if mode = 13
		mov ah,0h		;SCREEN 13; VGA
		mov al,13h
		int 10h
	end if

	pop ax
}

macro SLEEP
{
	;Output:
	;ah = BIOS scancode of key pressed
	;al = ASCII character of key pressed
	;Could have also used...
	;	mov ah,8h
	;	int 21h
	mov ah,0h
	int 16h
}

macro END
{
	mov ax,4Ch	;\END
	int 21h		;/
}

macro LOCATE row,col
{
	pusha

	mov ah,2		;Function 2
	mov bh,0		;Use page 0
	mov dh,row	;row
	mov dl,col		;col
	int 10h

	popa
}
And then you can do this:

Code: Select all

	SCREEN 0
	LOCATE 5,5
	PRINT "Hello World"
	SLEEP
	END

Posted: Sat Jun 07, 2008 7:08 pm
by tadada
Thank you for your help. I realised that because it places that code there I wouldn't need a ret line at the end but that wasn't the problem. I am going to try fasm.

Posted: Sat Jun 07, 2008 7:24 pm
by Dex
tadada wrote:Thank you for your help. I realised that because it places that code there I wouldn't need a ret line at the end but that wasn't the problem. I am going to try fasm.
But my point was, that unless you call the macro by placing its name some where in your code, it will not be assembled even if you put the code for the macro in your code.
You will not go far wrong with Fasm and they have a macro section
http://board.flatassembler.net/forum.ph ... 788d968625

Posted: Sat Jun 07, 2008 7:34 pm
by tadada
The thing is that in my kernel I do call the macro for print and clear screen. the line for clear screen reads: clrscrn

It has no parameters, its on it own line and it does nothing. It skips it as if it didn't compile it, but I did create it. In fact it thinks they are labels that I forgot to add the colon to. heck I even added a parameter and now it won't take it saying it is exspecting an instruction but it is in the syntax given in the manual.

Posted: Sun Jun 08, 2008 8:42 pm
by kmcguire
I wrote:

Code: Select all

%macro foo 0
        mov eax, 0x18
        mov es, eax
%endmacro

start:
        foo
        xor eax, eax
        foo
I assembled with:

Code: Select all

nasm -felf t.asm -o t
And, I also tried:

Code: Select all

yasm -rnasm -pnasm t.asm -o t
It produces:

Code: Select all

kmcguire@laptop ~ $ objdump -d t

t:     file format elf32-i386

Disassembly of section .text:

00000000 <start>:
   0:   b8 18 00 00 00          mov    $0x18,%eax
   5:   8e c0                   mov    %eax,%es
   7:   31 c0                   xor    %eax,%eax
   9:   b8 18 00 00 00          mov    $0x18,%eax
   e:   8e c0                   mov    %eax,%es
Which shows that the macro is working. You must be doing something wrong, or not checking your inputs and outputs good enough.

Posted: Mon Jun 09, 2008 5:38 am
by tadada
I know what I did wrong.

I had the file that contained the macros (scrn.inc) being included at the end of the kernel file but the preproccesor replaces the macro call with the most recent version of the macro. Because it was included after the call there as no recent version and thus it only could replace the macro call with nothing. Because there was nothing there it just assembled it without it thus giving the symptoms of it continueing without a problem.

hehe. I knew it had to be something simple.

I have one question though. In NASM does the macro automatically push various register because the putch macro in FASM works but in NASM is gives a general protection fault. They are the same other then the minor differences between the macro syntaxes like passing the char to print and saying when a macro ends thats all. EDIT: my bad had a ret statement in my marco.

I had success with FASM though, Now I just have to choose FASM or NASM both of which seem like great assemblers.

Posted: Mon Jun 09, 2008 1:14 pm
by Dex
One big plus for Fasm, is its very easy to port to your OS, if your OS can load a program, has a print function, basic memory management, and can load a source file.
Then it will take less than half a hour to port.

Posted: Mon Jun 09, 2008 1:28 pm
by tadada
I'm gunna use FASM because I eventually wanna be able to make programs on my OS and I like the fact that it is a bit simpler.

One thing with porting it though. Because my OS is pmode 32-bit I'll have to create a DPMI (DOS Protected Mode Interface) or port an existing one. ICK! Or I could take the easy way and come down into real-mode to run it temporarily. At least to begin with. Load it then jump to the code to execute it save my files and such then go back into pmode. O