[SOLVED] ASM Kernel

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
HiGuys
Posts: 6
Joined: Sun Oct 24, 2010 7:54 pm

[SOLVED] ASM Kernel

Post by HiGuys »

Hello everyone. I've decided to re-write my kernel(I wasn't too far anyway) from C/ASM to just ASM. This is for the purpose of using less resources and increasing speed. I've had a problem with printk for a while with it. I can print one character, but not a string. The code is as follows:

Code: Select all

[GLOBAL print_one]
[GLOBAL printk]

screen_x	equ 0
screen_y	equ 0
string		db "Hello, World!", 0

new_line:
    mov		byte [screen_x], 0
    add		byte [screen_y], 1

    ret

print_one:
; Temporarily use bx as a storage spot for the attrib/char
    mov		bh, 0x0F
    mov		bl, al

; Multiply the screen_y by 160 and put it in cx (attrib/char each column, times 80 columns per row)    
    mov		ax, [screen_y]
    mov		cx, 160
    mul		cx
    mov		cx, ax

; Multiply the screen_x by 2 and put it in dx (attrib/char each x value)
    mov		ax, [screen_x]
    mov		dx, 2
    mul		dx
    mov		dx, ax

; Put the attrib/char back into ax
    mov		ax, bx

; Put the x and y values into bx
    mov		bl, dl
    mov		bh, cl

; Put the video memory location into edi, then add on the x and y values
    mov		edi, 0xb8000
    mov		[es:edi], bx

; Put the attrib/char into video memory (At this time - AX=ATTRIB+CHAR, BX=X+Y, ES:EDI=VIDEO MEMORY+BX, DX=X, CX=Y)
    stosw

; Increment x
    add		byte [screen_x], 1

; If the x value is on the last value, goto a new line.
    cmp		byte [screen_x], 80
    je		new_line

    ret

printk:
; Put the sring in al, increment si, which contains a pointer to a string
    lodsb
    inc		si

; If al = 0x00, end of string
    cmp		al, 0
    je		   done

; Else, print the character
    call	print_one
    jmp       printk

done:
    mov	al, 'D'
    call	print_one

    call	new_line
I believe I've isolated the problem to the first line of printk, it's loading a 0 instead of the first byte of the string, which makes it stop, and I can't figure out why.
Last edited by HiGuys on Sun Oct 31, 2010 12:20 am, edited 1 time in total.
User avatar
Chandra
Member
Member
Posts: 487
Joined: Sat Jul 17, 2010 12:45 am

Re: ASM Kernel

Post by Chandra »

This might help you...

Code: Select all

column dw 0
row dw 0
string db "Hello, World!", 0
string2 db "Next test in progress...",0
done db "All test sucessfull!",0

mov si,string 
call printk
mov si,string2
call printk
mov si,done
call printk
cli
hlt

printk:
	mov ax,0xb800
	mov es,ax
	call printchar
	ret

printchar:
	mov di,[row]
	mov al,[si]
	cmp al,0
	jz finished
	mov [es:di],al
	mov bx,[row]
	inc bx
	inc bx
	mov [row],bx
	inc si
	jmp printchar

finished:
	call nextline
	ret

nextline:
	xor ax,ax
	mov ax,[column]
	inc ax
	mov [column],ax
	mov bx,[row]
	xor bx,bx
	mov cx,160
	mul cx
	mov [row],ax
	ret
I don't know if this is the best way to do but it works. Also remember that since you want to call this from external file, declare row, column, printk and printchar as global type.
[Note: Row is updated every time you print a character and column is updated everytime you change the line. So you need not worry about what value they carry ]
Programming is not about using a language to solve a problem, it's about using logic to find a solution !
HiGuys
Posts: 6
Joined: Sun Oct 24, 2010 7:54 pm

Re: ASM Kernel

Post by HiGuys »

I don't know how you got that to work, you can't move a string into si because the string is bigger. You would have to move it into esi, which doesn't work for me.
User avatar
Chandra
Member
Member
Posts: 487
Joined: Sat Jul 17, 2010 12:45 am

Re: ASM Kernel

Post by Chandra »

I don't know why it didn't work with you. I tested the code myself and works fine with me.
I'm using this code in my bootloader and it works fine with me.Are you sure you've setup the proper segment registers? I'll attach the sample bootloader and the kernel file(very simple one) here.
bootload.asm
(2.49 KiB) Downloaded 53 times
kernel.asm
(844 Bytes) Downloaded 78 times
Do assemble and let me know if this works or not.

Also note that I've not introduced filesystem yet so you must write the kernel to 2nd sector exactly after the bootloader(1st Sector) for this to work.

Best Regards,
Chandra
Programming is not about using a language to solve a problem, it's about using logic to find a solution !
User avatar
Combuster
Member
Member
Posts: 9301
Joined: Wed Oct 18, 2006 3:45 am
Libera.chat IRC: [com]buster
Location: On the balcony, where I can actually keep 1½m distance
Contact:

Re: ASM Kernel

Post by Combuster »

<Insert something about spoonfeeding being the worst kind of answer>
"Certainly avoid yourself. He is a newbie and might not realize it. You'll hate his code deeply a few years down the road." - Sortie
[ My OS ] [ VDisk/SFS ]
User avatar
Chandra
Member
Member
Posts: 487
Joined: Sat Jul 17, 2010 12:45 am

Re: ASM Kernel

Post by Chandra »

Oh, Really? :(
If you feel that's like spoonfeeding , a very big SORRY! :shock:
Programming is not about using a language to solve a problem, it's about using logic to find a solution !
User avatar
Solar
Member
Member
Posts: 7615
Joined: Thu Nov 16, 2006 12:01 pm
Location: Germany
Contact:

Re: ASM Kernel

Post by Solar »

The only solution is understanding. Providing a piece of source code is usually not the best way to foster such understanding. HiGuys wanted to understand why his kprintf loads a zero instead of the first character of the string. A good solution would give him not only a functional kprintf function, but also the knowledge not to make that particular mistake again.

Consider this: "I want to write my own OS but it doesn't work." - "Here, take Linux, that works."
Every good solution is obvious once you've found it.
HiGuys
Posts: 6
Joined: Sun Oct 24, 2010 7:54 pm

Re: ASM Kernel

Post by HiGuys »

Solar wrote:The only solution is understanding. Providing a piece of source code is usually not the best way to foster such understanding. HiGuys wanted to understand why his kprintf loads a zero instead of the first character of the string. A good solution would give him not only a functional kprintf function, but also the knowledge not to make that particular mistake again.

Consider this: "I want to write my own OS but it doesn't work." - "Here, take Linux, that works."
Yes, I do want to understand the code a little better, I got what most of the code is doing, just not the first lines of printk. On another note, this is an error coming from the linker, not the assembler. Does that have anything to do with it? All your code is in one file so you probably assemble that directly into the kernel. My code is split across three different files, and nasm won't take more than one, so I use ld. Is this a mistake?
User avatar
NickJohnson
Member
Member
Posts: 1249
Joined: Tue Mar 24, 2009 8:11 pm
Location: Sunnyvale, California

Re: ASM Kernel

Post by NickJohnson »

Are you using ELF (or PE) as an object format, or just flat binary? Flat binary objects cannot be linked. If you want to make your kernel a flat binary but you also want multiple files, you need to use ELF first (-felf for nasm), link the produced objects with ld, then convert the ELF executable to a flat binary.
HiGuys
Posts: 6
Joined: Sun Oct 24, 2010 7:54 pm

Re: ASM Kernel

Post by HiGuys »

NickJohnson wrote:Are you using ELF (or PE) as an object format, or just flat binary? Flat binary objects cannot be linked. If you want to make your kernel a flat binary but you also want multiple files, you need to use ELF first (-felf for nasm), link the produced objects with ld, then convert the ELF executable to a flat binary.
I was using aout format, now I switched to ELF and it say's "File format not recognized". Could this be that I'm running ld from DJGPP?
azblue
Member
Member
Posts: 147
Joined: Sat Feb 27, 2010 8:55 pm

Re: ASM Kernel

Post by azblue »

If al is being loaded with a zero than ds:si is pointing to a zero. Make sure your string pointer is set up correctly.

I see quite a few other problems too. mov [es:edi], bx does not add the contents of bx to edi, it loads the contents of bx into the 1st 2 bytes of the video memory.

Not only that, the contents of bx don't seem right anyway. You need it to be y*160+x*2. After computing y*160, you then load the lower 8 bits of it into the bh. That would only work if the screen width was 128 characters. It's not, so you end up with a number in bx that is essentially meaningless.

In printk, stosb increments si once, and then inc si increments it again. Get rid of the 2nd increment.
azblue
Member
Member
Posts: 147
Joined: Sat Feb 27, 2010 8:55 pm

Re: ASM Kernel

Post by azblue »

Higuys, are you in protected mode or real mode? Are all your segments 4GB? If ds if a 4GB segment and you're only using si, all you're doing is setting the lower 16 bits of esi while leaving the upper 16 to whatever they were before you called printk; that could be why your string pointer is wrong. Use esi, in addition to making the other corrections I mentioned.
User avatar
Owen
Member
Member
Posts: 1700
Joined: Fri Jun 13, 2008 3:21 pm
Location: Cambridge, United Kingdom
Contact:

Re: ASM Kernel

Post by Owen »

HiGuys wrote:
NickJohnson wrote:Are you using ELF (or PE) as an object format, or just flat binary? Flat binary objects cannot be linked. If you want to make your kernel a flat binary but you also want multiple files, you need to use ELF first (-felf for nasm), link the produced objects with ld, then convert the ELF executable to a flat binary.
I was using aout format, now I switched to ELF and it say's "File format not recognized". Could this be that I'm running ld from DJGPP?
DJGPP does not use or support Elf; it uses DJGPP-COFF
Post Reply