c - 自制内核内联汇编给出错误的寄存器名称错误。C
问题描述
我正在编写一个自定义内核(其中一些工作来自https://www.codeproject.com/Articles/664165/Writing-a-boot-loader-in-Assembly-and-C-Part)。这是错误
test.c: Assembler messages:
test.c:12: Error: bad register name `%dil'
ld: cannot find test.o: No such file or directory
objcopy: 'test.elf': No such file
这里是文件:
compile.sh
gcc -c -g -Os -march=x86-64 -ffreestanding -Wall -Werror test.c -o test.o
ld -static -Ttest.ld -nostdlib --nmagic -o test.elf test.o
objcopy -O binary test.elf test.bin
test.ld
ENTRY(main);
SECTIONS
{
. = 0x7c00;
.text : AT(0x7c00)
{
*(.text)
}
.sig : AT(0x7dfe)
{
SHORT(0xaa55)
}
}
这是c(与内联汇编混合)源
__asm__(".code16\n");
__asm("jmpl $0x0000, $main\n");
void printChar(char value);
void main() {
printChar('c');
printChar('i');
}
void printChar(char value) {
__asm__("movb %0, %%al\n"
"movb $0x0e, %%ah\n"
"int $0x10\n"
:
: "r" ( value )
);
}
我认为错误来自被破坏的寄存器约束(我玩了一点,但是因为我在 16 位中,因为这在引导扇区中,寄存器的行为与我认为的 64 位时不同)。非常感谢任何帮助。另外,请注意,即使是指导我正确方式的提示也足够了。我不一定需要修复 c 代码,我主要寻找的是为什么会发生此错误。谢谢编辑:
我尝试使用 March i686 进行编译,但它说 The cpu you selected doesn't support the x86-64 instructions set and - fcf-protection=full –</p>
我还在 gcc 行中添加了 m16 并且它可以编译,但是当我运行 ld 时,它说输入文件 test.o 的 i386 架构与 i385:x86-64 输出不兼容,所以 gcc 命令是 gcc -c -g -Os -游行=i686 -ffreestanding -Wall -Werror test.c -o test.o - m16
编辑:感谢@Peter Cordes,我找到了解决方法:
Build.sh
gcc -c -g -march=i686 -Os -ffreestanding -Wall -Werror test.c -o test.o -m32
ld -static -Ttest.ld -nostdlib --nmagic -o test.elf test.o -melf_i386
objcopy -O binary test.elf test.bin
And the c source code
__asm__(".code16\n");
__asm("jmpl $0x0000, $main\n");
void printChar(char value);
void main() {
printChar('c');
}
void printChar(char value) {
__asm__(
"int $0x10\n"
:
: "a"(value | (0x0e<<8))
);
}
我仍然没有理解 "a"(value | (0x0e<<8)) 的作用。有人可以给我一些很好的资源来学习内联汇编吗?
解决方案
像这样的寄存器%dil
仅在 64 位模式下可用。本教程使用该-march=i686
选项,但这假设您的编译器是针对 32 位环境构建的,而本机 Linux x86-64 编译器不是。
正如@Peter Cordes 指出的那样,您需要使用-m16
.
或者,如果您打算在本教程之外进行 OS 开发,则应考虑为通用目标环境构建适当的 gcc 交叉编译器。使用操作系统的本机编译器通常会导致操作系统开发出现问题。OSDev 的这个页面是一个很好的起点。
推荐阅读
- c# - 获取 Azure 活动目录令牌
- php - 使用一个html表单插入两个sql表
- vue.js - Nuxt serverMiddleware 从 API 获取 json
- c# - 我如何使用 for 循环初始化 T[] arr 类型的数组
- bash - 字母和数字上的 Bash shell 迭代
- ios - 设置 UIPopoverPresentationController 的 barButtonItem 时弹出箭头偏离中心
- python - Python Numpy 2D数组没有括号对齐
- java - Tomcat 8,在同一根目录下发布 2 .war
- typo3 - 我可以将 backend_user 图像添加到 tx_news 吗?
- python - Urllib 请求响应时间过长