我有以下代码,现在不起作用了。我记得几个月前它已经起作用了。也许这是编译器问题?
我正在使用一个小的操作系统。只是为了了解它是如何工作的。 我想开始使用C,因为它比汇编器更具可读性。
我的C代码是:
#ifndef _CODE16GCC_H_
#define _CODE16GCC_H_
asm(".code16gcc\n");
#endif
#define VIDEO_MEM 0xB8000
#define WIDTH 80
#define HEIGHT 25
asm("call main\n");
asm("xor %eax, %eax\n");
asm("xor %ebx, %ebx\n");
asm("int $0x21\n");
void main(void)
{
unsigned char* mem = (unsigned char*)VIDEO_MEM;
for(int x = 0; x < 80; x++)
{
for(int y = 0; y < 25; y++)
{
*mem = 'A';
mem++;
*mem = 0x07;
mem++;
}
}
asm("xor %ax, %ax;int $0x16;");
}
我用以下命令编译它:
gcc -m32 -Os -march=i686 -ffreestanding -fno-stack-protector -Wall -Werror print.c -o print.o
并使用以下链接:
ld -m elf_i386 -static -Tlinker.ld -nostdlib --nmagic print.o -o print.elf
并使用以下命令创建二进制文件:
objcopy -O binary print.elf -o print.bin
(这基本上是我们在大学中使用的makefile编写的一些bootloader)
我现在的问题是,产生的汇编代码似乎是错误的:
objdump -d -M intel print.o
产生:
print.o: file format elf32-i386
Disassembly of section .text:
00000000 <.text>:
0: 66 e8 fc ff callw 0 <.text>
4: ff (bad)
5: ff 66 31 jmp DWORD PTR [esi+0x31]
8: c0 66 31 db shl BYTE PTR [esi+0x31],0xdb
c: cd 21 int 0x21
Disassembly of section .text.startup:
00000000 <main>:
0: 66 ba 00 80 mov dx,0x8000
4: 0b 00 or eax,DWORD PTR [eax]
6: 66 31 c0 xor ax,ax
9: 67 c6 04 42 mov BYTE PTR [si],0x42
d: 41 inc ecx
e: 67 c6 44 42 01 mov BYTE PTR [si+0x42],0x1
13: 07 pop es
14: 66 40 inc ax
16: 66 83 f8 19 cmp ax,0x19
1a: 75 ed jne 9 <main+0x9>
1c: 66 83 c2 32 add dx,0x32
20: 66 81 fa a0 8f cmp dx,0x8fa0
25: 0b 00 or eax,DWORD PTR [eax]
27: 75 dd jne 6 <main+0x6>
29: 31 c0 xor eax,eax
2b: cd 16 int 0x16
2d: 66 c3 retw
主要功能本身对我来说看起来不错。但是在第一部分中发生了什么?我使用内联汇编编写的部分。它只是随机的指令,甚至是(坏的)位。
我肯定知道这曾经有用。但是我现在想念什么? 这是GCC 8.2.1的问题吗?还是我的代码不正确?
感谢您的帮助!