C Inline ASM: passing integers to a register

assembly, c

Solution

Write the asm set_cursor function to use the CDECL calling convention and you can avoid the inline asm entirely. Just use `extern void set_cursor(int x, int y)` and you can call it like any other C function. I use this for all asm in my own "kernel" (LGDT/IDT/etc). The only exception being setting cr3 for paging, since it's so simple.

Assuming Intel syntax, you could add:

set_cursor:
   mov     ecx, [esp + 4] # x in ecx (args are pushed right to left)
   mov     edx, [esp + 8] # y in edx

   push    ebx            # ebx has to be preserved in CDECL

   mov     bh, cl
   mov     bl, dl

   # Your original code...

   pop     ebx
   ret

Problem

I'm trying to make a simple kernel but I'm stucked on a cursor screen movement. My function, for move the cursor, is written in Assembly, but the rest of the kernel is in C, so I have to make a C function for call that function. And that's the C function: ``` void setCursor(unsigned int x, unsigned int y) { asm("mov (%0), %%bl" :: "r" (y) : "%bl"); asm("mov (%0), %%bh" :: "r" (x) : "%bh"); asm("call set_cursor"); } ``` In this function, I try to move the var `unsigned int x` to register `bh` and the other, `unsigned int y`, to register `bl`, and then call the function to move the cursor. The problem is when I call this function, the cursor disappear from the screen. I think the values `x` and `y` and registers values `bl` and `bh` are not the same. For give you an idea of that clue, I tested to pass values directly in the asm directive and it works: ``` void setCursor(unsigned int x, unsigned int y) { asm("mov $1, %bl"); asm("mov $2, %bh"); asm("call set_cursor"); } ``` Any help is welcome. And thanks in advance. :D Assembly output from compiler Ubuntu 12.04 64bit compiling in 32bit ``` setCursor: .LFB12: .cfi_startproc pushl %ebp .cfi_def_cfa_offset 8 .cfi_offset 5, -8 movl %esp, %ebp .cfi_def_cfa_register 5 movl 12(%ebp), %eax pushl %ebx .cfi_offset 3, -12 #APP # 131 "./kernel/screen.c" 1 mov (%eax), %bl # 0 "" 2 #NO_APP movl 8(%ebp), %eax #APP # 132 "./kernel/screen.c" 1 mov (%eax), %bh # 0 "" 2 # 133 "./kernel/screen.c" 1 call set_cursor # 0 "" 2 #NO_APP popl %ebx .cfi_restore 3 popl %ebp .cfi_def_cfa 4, 4 .cfi_restore 5 ret .cfi_endproc ```

Original source