nasm label problems

Question about which tools to use, bugs, the best way to implement a function, etc should go here. Don't forget to see if your question is answered in the wiki first! When in doubt post here.
Post Reply
libber

nasm label problems

Post by libber »

hi, i have my main kernel file, kernel.asm which includes the file functions.asm. within functions.asm, there is a function named simple_print, this function looks like this

Code: Select all


[global simple_print]

simple_print_label:
   ;args: point ds:si to the string you want to print
   cld   ;stosb increments esi, because DF is now clear
   
   mov eax, 160    ;160 decimal is 80*2, or chars_per_line*bytes per char
   mul ecx      ;ecx * eax, product in eax
   mov ecx, eax   ;move product from eax to rightful place
   mov eax, 0   ;clear eax cause we need it below

   ;video buffer starts at (pyscial) 0xb8000, 0xb8000 is the first char
   ; in the top left corner assuming a 80 char per line * 25 line screen
   ; so if we want to print starting on the second line we would put our
   ; text and color bytes at b8000 + A0 (160)
   ;video address is b800 in real mode so physical address is b8000

      .load_label
   lodsb   ;load byte (our letter) at ds:si into al

   mov [ds:0xb8000 + ecx], al   
   add ecx, 1
   mov [ds:0xb8000 + ecx], byte 0x07   ;color pattern, while on black
   add ecx, 1
   cmp al, 0
   jne load_label
   ret
so when i compile this nasm complains saying 'symbol simple_print_label redefined'. yet if i take this label out i cant declare the local label below it (.load_label). i have also made sure that this label is not redefined anywhere else. i have tried every combination of labels i can find yet i cannot find out how to fix this problem, it gives the same error if i rename simple_print_label also. i have looked through the nasm manual but been unable to find anything about this error or find a label that will work correctly for me. functions.asm is being compiled because it is an include file in kernel.asm which is being compiled as an aout file.

thanks for your time,
Collin
User avatar
Pype.Clicker
Member
Member
Posts: 5964
Joined: Wed Oct 18, 2006 2:31 am
Location: In a galaxy, far, far away
Contact:

Re:nasm label problems

Post by Pype.Clicker »

oow ooow ooooow.

what are you doing with your labels ??

you want to have a function called "simple_print", right ? (as suggested by the [global simple_print] statement)
then why don't you simply write down

Code: Select all

[global simple_print]

simple_print:
   ;args: point ds:si to the string you want to print
   cld   ;stosb increments esi, because DF is now clear
...
what is that "_label" suffix for ?

also, if you declare a local ".load_label" (may i suggest a colon after this one ?), why are you jumping to "jne load_label" instead of "jne .load_label" ?

by the way, you say it's an "include of kernel.asm", did you make sure it was included *once and only once* ? You can do this with the magicae formulae

Code: Select all

%ifndef __KERNEL_PRINT_SIMPLE
%define __KERNEL_PRINT_SIMPLE
print_simple:
 ...
 ret
%else
%warning "attempt to re-declare print_simple"
%endif
User avatar
Solar
Member
Member
Posts: 7615
Joined: Thu Nov 16, 2006 12:01 pm
Location: Germany
Contact:

Re:nasm label problems

Post by Solar »

Pype.Clicker wrote: oow ooow ooooow.
...did you make sure it was included *once and only once* ? You can do this with the magicae formulae...
For the paranoid, don't define this "header guard" to just nothing, but rather define it to be itself:

Code: Select all

%ifndef __KERNEL_PRINT_SIMPLE
%define __KERNEL_PRINT_SIMPLE __KERNEL_PRINT_SIMPE
The trick here is that, even with the off-chance of some identifier being named exactly like the header guard, the guard still would not break anything.
Every good solution is obvious once you've found it.
libber

Re:nasm label problems

Post by libber »

ok, i have made sure functions.inc has been included only once in kernel.asm. i have made the changes you suggested pype but unfortinetly it still fails. nomatter what name i change 'simple_print_label' to it fails saying 'functions.inc: simple_print_labels_new_name redefined'. i am calling simple print from kernel.asm by just including functions.inc and calling simple_print, but i also tried doing 'extern simple_print' but then it just gives me the above error agian this time in kernel.asm. thanks for your suggestions and speedy replies.

thanks for your time,
Collin
Schol-R-LEA

Re:nasm label problems

Post by Schol-R-LEA »

At the risk of sounding peremptory or dismissive, I'd recommend that you review the concepts of [tt]include[/tt] files and assembly language labels before proceeding. These are two previous explanations I've given on those subjects:

Reply #9 (discusses C preprocessor [tt]#include[/tt] directive, but applies to the NASM [tt]%include[/tt] as well)
Reply #4

The point is that there is no difference between the name of a function and the label marking it's start point; the label is the function 'name', or rather, it is the address of the function's entry point. Using a [tt][[global]][/tt] or an [tt][[extern]][/tt] directive doesn't change that fact. The purpose of those two directives is for indicating to the linker the visiblity of labels between separately assembled object files; since you are (if I read this correctly) creating a flat binary image, that's not even possible in this case. See the NASM Reference for more details on these issues.

Sorry for the rather brusque answers, but I'm rather short on time right now. I'll try to get back to this later if this isn't clear.
libber

Re:nasm label problems

Post by libber »

ok, it was very useful for me to read up on those topics Schol-R-LEA and not the least bit offsensive, thanks for those links. unfortinetly even with that knowledge i am still having some problems, i did alot of testing today and will explain to you all that i know.

i have kernel.asm and functions.asm. i assemble them both, then link them like ld kernel.o functions.o (not the actuial command just to signify i have kernel.o ahead of functions.o if it matters which i am not sure if it does.).

i have tried including the functions in functions.asm a number of ways

just an extern in kernel.asm of the function name i want to use (blah for example) i put 'extern blah' in kernel.asm, when i do so i get a linker error saying 'undefined refernce to blah

if i do an %include functions.asm in kernel.asm and take out the extern blah, i get an assembler error saying 'symbol blah undefined', i also get an error saying 'phase error at end of assembly'.

if i do an %include functions.asm and an extern blah (function blah is resident in functions.asm) i get the error 'error: no special symbol features supported here'. i am thinking this may be a problem with the file format i am using (a.out) but i thought bin format was the only one to not support symbols?

also, just as a quick question, should i fill the idt with "filler" interrupts before or after remapping the pic?

thanks for your time,
Collin
User avatar
Pype.Clicker
Member
Member
Posts: 5964
Joined: Wed Oct 18, 2006 2:31 am
Location: In a galaxy, far, far away
Contact:

Re:nasm label problems

Post by Pype.Clicker »

small picture may help more than lot of words ...
(hope so)

here comes the 3 schemes i can think of: including functions, linking modules or including macros ...

in each case, you'll notice that you should have only *one* %include and preferably at the start of kernel.asm in the latter case.

note that i'm unsure .$local is a local in a macro, but there's something like this looking somewhat like this ... just check your NASM manual to be sure ;)

[attachment deleted by admin]
libber

Re:nasm label problems

Post by libber »

ok i also noticed that if i include a file, it changes the flow of execution, even if i dont call it! now this is really strange....

when i include functions.asm in kernel.asm and break at 0x100000 (the address i have my bootloader move the compiled kernel.asm to) if i include functions.asm 0x100000 is inside that file!

example to clarify
kernel.asm first 3 lines
nop
nop
jmp

functions.asm
nop
mov eax, 1234
nop

soo, when i include functions.asm and start executing at 0x100000, i see 'nop, mov eax, nop' which is definetly not what i expect to see! also keep in mind i am not even calling anything in fucntions.asm it just starts executing there. mabey this is because %include just throws the code form the include file at the top of your file?! that is the only thing i could think of.

anyhow do note that i am compiling both kernel.asm and functions.asm in aout format. i will include my ugly little build script here in hopes that it might shine some light on what i am doing wrong. i am sure it is just me not understanding something.

Code: Select all

 
rm part1
rm part2
rm part2.o
rm kernel.img
nasm   -f bin bootloader.asm -o part1
nasm  -f aout kernel.asm -o part2.o
nasm -f aout functions.asm -o functions.o
ld -T link.ld  --warn-common --export-dynamic -o part2 part2.o functions.o
cat part1 > kernel.img
cat part2 >> kernel.img
thanks for your time,
Collin
bkilgore

Re:nasm label problems

Post by bkilgore »

mabey this is because %include just throws the code form the include file at the top of your file?!
That's *exactly* what include does, as you read in Schol-R-LEA's reply #9 that he directed you to.

Also, if you're building them separately, I do hope that you're not still %including one in the other. As Pype showed in his diagrams, you only include one in the other in the two cases where you don't compile them both. when you do, you just link them together and the linker takes care of it. You don't include one in the other, then you just end up with duplicate code because the functions code exists in both the functions.asm file and the post-processed kernel.asm.
libber

Re:nasm label problems

Post by libber »

ok, i read his post but was confused, i thought that including something only included the function prototypes. ok well i understand what i should be doing, and have tried a few different things.

1) i checked on aout file format and it looks like it supports symbols so doing extern and global should work with it right?

2) while i am pretty sure i understand the basics of include and what it should and shouldn't do, i keep on getting 'error: symbol blah redefined' why might this be?

3) is the syntax for my linker in my little build script correct?

4) it seems like just putting a jump at the beginning of my functions.asm that jumps to the end of functions.asm which would then fall into kernel.asm would work,,, but i dont think this is the way i want to do it...

as always, thanks alot for your time,
Collin
Schol-R-LEA

Re:nasm label problems

Post by Schol-R-LEA »

Look at it this way: if you have two files, org.asm and phant.asm:

Code: Select all

; org.asm
; the main program

%include "phant.asm"

; beginning of program
main: 
       mov message, si
       call print
       jmp $

message db "Hello, World!", 0x00
and

Code: Select all

; phant.asm
; a printing function used by org.asm

print:
      push ax
      mov ah, 0x0E      ; set function to 'teletype mode'
.loop:   
      lodsb             ; update byte to print by copying the value
                           ; pointed to by SI into AL
      cmp al, 0x00  ; test that it isn't zero
      jz .endstring
      int 0x10     ; put character in AL at next cursor position
      jmp short .loop

.endstring:
      pop ax
      ret

; the end of phant.asm
Then, what the assembler sees is after the [tt]%include[/tt] directive is handled by the macro preprocessor is

Code: Select all

; org.asm
; the main program

; phant.asm
; a printing function used by org.asm

print:
      push ax
      mov ah, 0x0E      ; set function to 'teletype mode'
.loop:   
      lodsb             ; update byte to print by copying the value
                           ; pointed to by SI into AL
      cmp al, 0x00  ; test that it isn't zero
      jz .endstring
      int 0x10     ; put character in AL at next cursor position
      jmp short .loop

.endstring:
      pop ax
      ret

; the end of phant.asm

; beginning of program
main: 
       mov message, si
       call print
       jmp $

message db "Hello, World!", 0x00
Clear? The [tt]%include[/tt] statement simply inserts the whole text of the included file into the the text of the file that includes it, no more and no less. The use of [tt]%include[/tt] for handling function prototypes and such is solely a convention; the [tt]%include[/tt] directive doesn't create function prototypes or affect the linking at all. All it does is cut and paste text.

So, then, the reason you are getting the 'symbol redefined' error is because you are defining it twice: once in functions.asm, and then again in functions.asm, which is textually duplicated in kernel.asm at assembly time by the [tt]%include[/tt] statement. Clear?

If you are assembling the files separately, and then linking them, you don't need to [tt]%include[/tt] functions.asm in kernel.asm. Conversely, if you [tt]%include[/tt] functions.asm in kernel.asm (and you'd probably want to place it at the end of the file if you do), then you don't need to assemble both of them and link them together.

If you assembly them separately, then you do need to have a [global simple_print] statement in functions.asm (but not kernel.asm), so that the label gets put into function.o's linkage table for exporting; and you need an [extern simple_print] statement in kernel.asm (but not functions.asm) so that the symbol is marked as importable in kernel.o's linkage table. But if you do that, then a) don't also use [tt]%include[/tt]. lest it causes a double definition, and b) make sure that the exported label is the same as the actual label in the code.

Once again, it would help considerably if you post the actual code, whether in the message or as an attachment. HTH.
libber

Re:nasm label problems

Post by libber »

ah, that is so very prefectly clear, thats for taking the time to explain it to me (not your communications skills fault, but my understanding skills) now i will run off and try to impliment it and report back :)
beyond infinity lazy

Re:nasm label problems

Post by beyond infinity lazy »

org.asm, phant.asm ... *rofl* ... humor is a fine thing.
Post Reply