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.
Hey,
I've tried to implement a simple printk() function in assembly. Just for learning purposes because my assembly knowledge is the absolute minimum. It is not really working.
This is my assembly routine I've programmed.
1 [GLOBAL _printk]
2
3 _printk:
4 mov edx, [esp+8] ; get address passed as parameter
5 mov esi, 2 ; later we multiply it by two
6 print_loop:
7 mov bh, 0x07 ; setting background color to black and foreground to light grey
8 mov eax, ecx ; ecx is i: move it to eay
9 add eax, edx ; edx ist the current address: 0x000 + 2 e.g.
10 mov bl, [eax] ; the ascii code is fetched
11 cmp bl, 0 ; if it is a null byte
12 je finish ; we're finish
13 mov eax, ecx ; put ecx again in eax
14 mul esi ; multiply it by two
15 add eax, 0xB8000 ; add the VGA base address
16 mov [eax], bx ; write charakter to address
17 inc ecx ; increment i
18 jmp print_loop ; go to beginning
19 finish:
20 xor esi, esi
21 ret ; return
19 section .data
20
21 msg: db "A", 0 ; Here I create the message to display
22 section .text
23 push msg ; Here I push it on the stack
24 extern _printk
25 call _printk ; call the function
26 add esp, 4 ; remove it from the stack
I think the problem is when passing the address of the string. Because there is absolutely nothing printing(null byte at beginning?). I have no idea how to fix it.
[GLOBAL _printk] ; for compatibility with windows
[GLOBAL printk] ; and *nix
%define sizeof_ptr 4
_printk:
printk:
push ebp ; Push used registers
mov ebp, esp ; Save stack pointer to ebp
add ebp, sizeof_ptr ; We added ebp to stack, so decrease (i.e. increase) it
push eax ; Push used registers
push ebx
push ecx
push edx
push esi
mov edx, [ebp+sizeof_ptr] ; get address passed as parameter
mov esi, 2 ; later we multiply it by two
.print_loop:
mov bh, 0x07 ; setting background color to black and foreground to light grey
mov eax, ecx ; ecx is i: move it to eay
add eax, edx ; edx ist the current address: 0x000 + 2 e.g.
mov bl, [eax] ; the ascii code is fetched
cmp bl, 0 ; if it is a null byte
je .finish ; we're finish
mov eax, ecx ; put ecx again in eax
mul esi ; multiply it by two
add eax, 0xB8000 ; add the VGA base address
mov [eax], bx ; write charakter to address
inc ecx ; increment i
jmp .print_loop ; go to beginning
.finish:
pop esi ; Restore used registers
pop edx
pop ecx
pop ebx
pop eax
pop ebp
ret ; return