簡體   English   中英

自制內核內聯匯編給出了錯誤的寄存器名稱錯誤。 C

[英]Homemade kernel Inline assembly gives bad register name error. 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 進行編譯,但它說您選擇的 CPU 不支持 x86-64 指令集和 - fcf-protection=full -

我還將 m16 添加到 gcc 行並進行編譯,但是當我運行 ld 時,它說輸入文件 test.o 的 i386 架構與 i385:x86-64 輸出不兼容,因此 gcc 命令是 gcc -c -g -Os - March=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

或者,如果您打算在本教程之外進行操作系統開發,您應該考慮為通用目標環境構建一個合適的 gcc 交叉編譯器。 使用操作系統的本機編譯器通常會導致操作系統開發出現問題。 OSDev 的這個頁面是一個很好的起點。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM