printk in assembler

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
ostylk
Posts: 9
Joined: Fri Feb 13, 2015 12:38 pm

printk in assembler

Post by ostylk »

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.

Code: Select all

  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
Then in my kernel_main I do something like this:

Code: Select all

 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.
alexfru
Member
Member
Posts: 1112
Joined: Tue Mar 04, 2014 5:27 am

Re: printk in assembler

Post by alexfru »

How about you review your code line by line? When you get to line 8, you may get your first clue.
wordnice
Posts: 6
Joined: Sat Jun 20, 2015 1:22 pm
Libera.chat IRC: wordnice

Re: printk in assembler

Post by wordnice »

You should push used registers at the begining and pop them before function return.

So, for example (untested):

Code: Select all

[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
Post Reply