让 C 与汇编一起工作
Getting C to wok with assembly
我正在做一个简单的 OS,在过去的 3 周里,我一直在调试一个错误,该错误仅在我在汇编中调用 c++ 或 c 代码时出现,qemu(我使用的模拟器)将开始闪烁并且不会加载代码。我已经用其他模拟器试过了。
"Bootloader.asm"
[org 0x7c00]
mov ah, 0x00
mov al, 0x03
int 0x10
mov [Boot_Disk], dl
mov bp, 0x7c00
mov sp, bp
call DiskRead
jmp Program_Space
jmp $
%include "ReadDisk.asm"
times 510 - ($ - $$) db 0 ;fills the rest of the bytes till byte 510 with 0s
db 0x55 ;sets the last 2 bytes to 0x55 and 0xaa, so the bios knows its bootable
db 0xaa
"Sector2.asm"
jmp Enable32BitMode
%include "gdt.asm"
Enable32BitMode:
call enable_A20
cli ;disables interupts
lgdt [gdt_descriptor]
mov eax, cr0
or eax, 1 ; set PE (Protection Enable) bit in CR0 (Control Register 0)
mov cr0, eax
jmp codeseg:Start32Bit
enable_A20:
in al, 0x92
or al, 2
out 0x92, al
ret
[bits 32]
;[extern _start]
Start32Bit:
mov ax, dataseg ;moves dataseg (found in gdt, into registers ds to gs)
mov ds, ax
mov ss, ax
mov es, ax
mov fs, ax
mov gs, ax
;mov [0xb8000], byte 'h'
; call _start
jmp $
times 2048 - ($-$$) db 0 ;fills the disk with 2kb of 0's
"ReadDisk.asm"
Program_Space equ 0x7e00
DiskRead:
mov ah, 0x02
mov bx, Program_Space
mov al, 4 ;amount of sectors to read
mov dl, [Boot_Disk]
mov ch, 0x00 ;
mov dh, 0x00 ;
mov cl, 0x02 ;
int 0x13
"ReadText.cpp"
extern "C" void _start() {
return;
}
我的编译器选项(linux):
nasm Bootloader.asm -f bin -o Bootloader.bin
nasm Sector2.asm -f elf32 -o Sector2.o
gcc -ffreestanding -m32 -mno-red-zone -march=i686 -c "Kernel.c" -o "ReadText.o" # -m32
ld -m elf_i386 -o Kernel.tmp -Ttext 0x7e00 Sector2.o ReadText.o
objcopy -O binary Kernel.tmp Kernel.bin
cat Bootloader.bin Kernel.bin > Bootloader.flp
c代码反汇编:
Disassembly of section .text:
00000000 <_start>:
0: f3 0f 1e fb endbr32
4: 55 push %ebp
5: 89 e5 mov %esp,%ebp
7: 90 nop
8: 5d pop %ebp
9: c3 ret
喜欢@jester 评论了你的问题。您似乎将引导加载程序编译为 .code32。您的 CPU(qemu 或任何其他 VM)无法启动它,因为 CPU 最初以 16 位模式运行。请看这里 - JOS bootloader 。这是您可以学习的简约引导加载程序。
我发现了错误,我没有读取保存 C 代码的扇区,如果您在阅读此文件时遇到这个问题,请确保您正在读取所有扇区。
我正在做一个简单的 OS,在过去的 3 周里,我一直在调试一个错误,该错误仅在我在汇编中调用 c++ 或 c 代码时出现,qemu(我使用的模拟器)将开始闪烁并且不会加载代码。我已经用其他模拟器试过了。
"Bootloader.asm"
[org 0x7c00]
mov ah, 0x00
mov al, 0x03
int 0x10
mov [Boot_Disk], dl
mov bp, 0x7c00
mov sp, bp
call DiskRead
jmp Program_Space
jmp $
%include "ReadDisk.asm"
times 510 - ($ - $$) db 0 ;fills the rest of the bytes till byte 510 with 0s
db 0x55 ;sets the last 2 bytes to 0x55 and 0xaa, so the bios knows its bootable
db 0xaa
"Sector2.asm"
jmp Enable32BitMode
%include "gdt.asm"
Enable32BitMode:
call enable_A20
cli ;disables interupts
lgdt [gdt_descriptor]
mov eax, cr0
or eax, 1 ; set PE (Protection Enable) bit in CR0 (Control Register 0)
mov cr0, eax
jmp codeseg:Start32Bit
enable_A20:
in al, 0x92
or al, 2
out 0x92, al
ret
[bits 32]
;[extern _start]
Start32Bit:
mov ax, dataseg ;moves dataseg (found in gdt, into registers ds to gs)
mov ds, ax
mov ss, ax
mov es, ax
mov fs, ax
mov gs, ax
;mov [0xb8000], byte 'h'
; call _start
jmp $
times 2048 - ($-$$) db 0 ;fills the disk with 2kb of 0's
"ReadDisk.asm"
Program_Space equ 0x7e00
DiskRead:
mov ah, 0x02
mov bx, Program_Space
mov al, 4 ;amount of sectors to read
mov dl, [Boot_Disk]
mov ch, 0x00 ;
mov dh, 0x00 ;
mov cl, 0x02 ;
int 0x13
"ReadText.cpp"
extern "C" void _start() {
return;
}
我的编译器选项(linux):
nasm Bootloader.asm -f bin -o Bootloader.bin
nasm Sector2.asm -f elf32 -o Sector2.o
gcc -ffreestanding -m32 -mno-red-zone -march=i686 -c "Kernel.c" -o "ReadText.o" # -m32
ld -m elf_i386 -o Kernel.tmp -Ttext 0x7e00 Sector2.o ReadText.o
objcopy -O binary Kernel.tmp Kernel.bin
cat Bootloader.bin Kernel.bin > Bootloader.flp
c代码反汇编:
Disassembly of section .text:
00000000 <_start>:
0: f3 0f 1e fb endbr32
4: 55 push %ebp
5: 89 e5 mov %esp,%ebp
7: 90 nop
8: 5d pop %ebp
9: c3 ret
喜欢@jester 评论了你的问题。您似乎将引导加载程序编译为 .code32。您的 CPU(qemu 或任何其他 VM)无法启动它,因为 CPU 最初以 16 位模式运行。请看这里 - JOS bootloader 。这是您可以学习的简约引导加载程序。
我发现了错误,我没有读取保存 C 代码的扇区,如果您在阅读此文件时遇到这个问题,请确保您正在读取所有扇区。