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
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
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.
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