Page 1 of 1

ASM Variable help

Posted: Sun Nov 08, 2009 6:49 pm
by ChrisSkura
ok, I just got my kernel working off boot up and it is just a simple kernel written in assembly. it loads and I can print out SINGLE characters to the screen using

Code: Select all


[ORG 0x7c00]

start:
    mov ah, 0ah
    mov al, "X"
    mov cx, 1

    int 10h
    
but when I try to print out strings, it doesn't work. if I put

Code: Select all

[ORG 0x7c00]

start:

    mov al, 12h
    mov ah, 0
    int 10h    

    jmp Draw

    msg db "Hello, World!$"

Draw:
    
    mov ah, 13h
    mov bh, 0
    mov bl, 0101b
    mov cx, 13
    mov dl, 10
    mov dh, 2
    mov bp, msg
    mov al, 1
    
    int 10h

    jmp end

end:
    
    jmp $
    times 510 - ($ - $$) db 0
the variables are all messed up but if I take out

Code: Select all

[ORG 0x7c00]
the variables work fine but it won't boot up.
Even if I assign integers to the variables and try to change the color of a single pixel with it's x and y coordinates set to the variables, the wrong pixel gets colored!

it seems that the variables are buggy no matter what I do and all of my code is correct.
I looked around for a long time and couldn't find anything.

Re: ASM Variable help

Posted: Sun Nov 08, 2009 6:54 pm
by neon
Hello,

org 0x7c00? Looks like a bootloader not a kernel.

In any case, sense you are in real mode and have org 0x7c00 put this at the start of your program:

Code: Select all

mov ax, 0x0
mov ds, ax
mov es, ax
mov ss, ax
mov fs, ax
mov gs, ax
Make sure to set ESP to a proper location for a stack before going further. Not doing so can result in a crash.

*edit: Also, your string does not need to end in $. Or, anything actually when using that interrupt as you pass in the size of the string in CX.

Re: ASM Variable help

Posted: Sun Nov 08, 2009 7:10 pm
by iocoder
You use only [ORG 0x7c00] when you right a boot-loader, as a kernel you shouldn't put [ORG 0x7c00] yet, but i want to say that you put this keyword to inform the assembler that this program will be loaded to 0x7C00 offset in memory. Your assembler organizes the program depending on this offset. But Kernel really isn't loaded to 0x7C00, or you should load it to 0x1000:0x7C00 and set DS to 0x1000 and ES to 0x1000 and so on.

Re: ASM Variable help

Posted: Sun Nov 08, 2009 8:57 pm
by ChrisSkura
nothing worked. I try outputting a string with a variable like this:

Code: Select all

[BITS 16]    ; 16 bit code generation
[ORG 0x1000:0x7C00]    ; ORGin location is 7C00

main:
MOV BH, 00h
MOV BL, 07h
MOV AL, 1
MOV BH, 0
MOV BL, 0101b
MOV CX, 13 
MOV DL, 30
MOV DH, 0
MOV BP, msg
MOV AH, 13h
INT 10h
JMP end

msg DB "Hello, World!"

end:
JMP $
TIMES 510-($-$$) DB 0 
and all that the string says is DIRECTORY IN.

I also tried the

Code: Select all

[org 0x1000:0x7c00]

mov ax, 0x0
mov ds, ax
mov es, ax
mov ss, ax
mov fs, ax
mov gs, ax
and it didn't help at all. it made the variables atleast appear with the pixel change thing but they're still buggy so I still can't use them.

I am using the NASM assembler and am making it a .exe file just so I could test it quikly without shutting down my computer so i don't know if that would have something to do with it.

it's ONLY the variables that are messed up. if I have no variables it works perfectly. I also don't know if this could be an error with nasm...

Re: ASM Variable help

Posted: Sun Nov 08, 2009 9:29 pm
by NickJohnson
ChrisSkura wrote:I [...] am making it a .exe file just so I could test it quikly without shutting down my computer so i don't know if that would have something to do with it.
Err... you need to be in a real mode environment for that code to work - Windows is quite far from that. Maybe you should read this. You can't write a flat binary designed for the bare hardware in real mode and expect it to work the same under a protected mode OS in a userspace environment, or even just protected mode for that matter.

Re: ASM Variable help

Posted: Sun Nov 08, 2009 9:31 pm
by neon
Hello,
and it didn't help at all. it made the variables atleast appear with the pixel change thing but they're still buggy so I still can't use them.
Keep that code in. The problem happens to do with real mode segment:offset addressing. The code I provided set the segments to 0 so they will not effect your offsets (do to your org 0x7c00).

Is this a boot loader or a kernel? You say kernel, however your code heavily implies that you are writing boot code do to your original org 0x7c00, it being limited to 512 bytes, and it being real mode assembly. If it is boot code (that is first executed by the BIOS), you should either have org 0x7c00, or org 0 with segments set to 0x7c0 (..or what I suggested above, org 0x7c00 with segments 0.) (..you are also missing the boot signature.)

You using 0x1000:0x7c00 suggests a lack of understanding of real mode addressing. If you do not have much experience with how real mode addressing works, it is highly recommended to read this great tutorial on how it works.

You said that you are making an EXE file. However, your code looks like it is flat binary. I suspect something is wrong :? Perhaps if you can provide the exact steps that you are taking to build and compile, and the exact type of project that you are making we can provide better help.

(Nick-There are 16 bit EXE's ;) Although im betting hes using 32 bit I just wanted to point that out )

Re: ASM Variable help

Posted: Sun Nov 08, 2009 9:45 pm
by ChrisSkura
I am making a kernel but since it is so small, I am not making a boot loader yet.

to assemble it I type in

Code: Select all

c:\nasm.exe c:\boot.asm -f bin -o c:\boot.exe
or if I am using it to boot off a floppy disk I type

Code: Select all

c:\nasm.exe c:\boot.asm -f bin -o c:\boot.bin
to save it to the floppy disk I type in

Code: Select all

debug c:\boot.bin

-w 100 0 0 1
I test the .exe on 32 bit xp

Re: ASM Variable help

Posted: Sun Nov 08, 2009 9:50 pm
by ChrisSkura
this is my project code so far.

Code: Select all

[BITS 16]
[ORG 0x1000:0x7c00]

jmp start

xstart dw 100
ystart dw 100
xend   dw 540
yend   dw 540

color  db 1

start:
	
    mov ax, 0x0
    mov ds, ax
    mov es, ax
    mov ss, ax
    mov fs, ax
    mov gs, ax

    mov ah, 0
    mov al, 12h
    mov ax, 4f02h
    mov bx, 106
 
    int 10h

    mov al, 1
    mov ah, 0ch

    mov cx, xstart

drawhor:

    mov dx, yend
    int 10h

    mov dx, ystart
    int 10h

    inc cx
    cmp cx, xend

    jnz drawhor

drawvert:
 
    mov cx, xstart
    int 10h

    mov cx, xend
    int 10h
    inc dx
    cmp dx, yend
    jnz drawvert

end:

    jmp $ 
    times 512 - ($ - $$) db 0

Re: ASM Variable help

Posted: Sun Nov 08, 2009 11:07 pm
by neon
Hello,

There are a couple of issues:

Code: Select all

c:\nasm.exe c:\boot.asm -f bin -o c:\boot.exe
This does NOT produce a valid executable file. It is just a flat binary program in disguise. Executing it in Windows should produce this message.

Code: Select all

-w 100 0 0 1
This writes to sector 0 of the floppy disk. This means that you are writing boot code not a kernel. Take your ORG statement out and use ORG 0x7c00. Also, it should end with this. Else some BIOSs might not boot it. Replace times 512 - ($ - $$) db 0 with:

Code: Select all

TIMES 510-($-$$) DB 0
DW 0xaa55 ; boot signiture
Also, I am not seeing any stack setup. That is asking for a crash.

Finally, it is important to note that mov dx, yend might not do what you expect. This takes the address of the variable, yend, into DX. If you want the data inside of the variable, use mov dx, [yend]

Be cautious of putting graphics in your bootloader (yes, not kernel) - you are limited to 512 bytes, which is quite small.

Re: ASM Variable help

Posted: Sun Nov 08, 2009 11:47 pm
by ChrisSkura
i know this may sound like a noob question but how do i make a stack?
I've never neede one before to run my program.

Re: ASM Variable help

Posted: Mon Nov 09, 2009 12:05 am
by ChrisSkura
k, this is my new one

Code: Select all

[BITS 16]
[org 0x7c00]

start:
    
    mov ax, 0x0
    mov ds, ax
    mov es, ax
    mov ss, ax
    mov fs, ax
    mov gs, ax

    mov ah, 00
    mov al, 12h
    int 10h

    MOV AL, 1
    MOV BH, 0
    MOV BL, 0101b
    MOV CX, 17 		; calculate message size. 
    MOV DL, 30
    MOV DH, 0
    PUSH CS
    POP ES
    MOV BP, msg
    MOV AH, 13h
    INT 10h

    MOV BL, 0010b
    MOV CX, 29
    MOV DL, 15
    MOV DH, 7
    PUSH CS
    POP ES
    MOV BP, made_by
    int 10h

    jmp end

    msg db "Welcome to my OS!"
    made_by db "This made by me, Chris Skura!"

end:

    jmp $
    times 510 - ($ - $$) db 0

    DW 0xAA55
it works perfectly and it outputs the strings with the right characters and in the right position.

Re: ASM Variable help

Posted: Mon Nov 09, 2009 6:06 am
by neon
Hello,

It is great to hear that you got it working. The top of your stack is stored in ESP, so to make a stack just set ESP to a good, known value. It is highly recommended to set up a stack because your code (not exactly your code, but the BIOS interrupts that you are using) may use push/pop or other instructions that manipulate the stack. If the stack is not located at a good, known location, then it is just as dangerous as working with a wild pointer - you dont know when or what might be overwritten.

Re: ASM Variable help

Posted: Mon Nov 09, 2009 6:37 am
by iocoder
i know this may sound like a noob question but how do i make a stack?
if you want to make a stack, you just need first to select the range of memory for this stack, you can make it from 0x0000:0x8000 (Stack Bottom) and ends at 0x0000:0xFFFF (Stack Top).
If you want your stack to be 64KB long, you can make it starts (for example) from 0x1000:0x0000 [Stack Bottom] to 0x1000:0xFFFF [Stack Top].

second set SS to 0x1000 and SP to the stack Top (0xFFFF):

Code: Select all

mov ax, 0x1000
mov ss, ax
mov sp, 0xFFFF

Re: ASM Variable help

Posted: Mon Nov 09, 2009 6:52 am
by qw
Note: after setting the SS register, the x86 processor disables interrupts for exactly one instruction, so you should set your SP immediately after SS.

Roel