C 内联 ASM : passing integers to a register

标签 c assembly

我正在尝试制作一个简单的内核,但我卡在了光标屏幕移动上。 我的移动光标函数是用汇编语言编写的,但内核的其余部分是用 C 语言编写的,所以我必须创建一个 C 函数来调用该函数。这就是 C 函数:

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");
}

在这个函数中,我尝试移动 var unsigned int x 来注册 bh 和另一个 unsigned int y 来注册bl,然后调用移动光标的函数。

问题是当我调用这个函数时,光标从屏幕上消失了。我认为值 xy 以及寄存器值 blbh 是不一样的。为了让您了解该线索,我测试了直接在 asm 指令中传递值并且它有效:

void setCursor(unsigned int x, unsigned int y) {
    asm("mov $1, %bl");
    asm("mov $2, %bh");
    asm("call set_cursor");
}

欢迎任何帮助。并提前致谢。 :D

编译器的汇编输出 Ubuntu 12.04 64位在32位编译

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

最佳答案

编写 asm set_cursor 函数以使用 CDECL 调用约定,您可以完全避免内联 asm。只需使用 extern void set_cursor(int x, int y),您就可以像调用任何其他 C 函数一样调用它。我将它用于我自己的“内核”(LGDT/IDT/等)中的所有 asm。唯一的异常(exception)是为分页设置 cr3,因为它非常简单。

假设使用 Intel 语法,您可以添加:

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

关于C 内联 ASM : passing integers to a register,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23160655/

相关文章:

assembly - 我如何在 NASM x86 中定义宏

assembly - 什么是被调用者和调用者保存的寄存器?

c - 具有用于 EAP-TLS 的原始套接字的 OpenSSL

c - 使用 Xlib 库删除或移除一行

c - 从 PCM 中删除 channel

linux - 调用 0x16 时出现段错误

assembly - 在 MIPS/SPIM 中,li 和 lw 有什么区别?

c - 当我将它与 protobuf 生成的文件链接时,openssl 中的程序核心

c - 空结构 typedef

用于汇编样式十六进制数字的 C# 正则表达式