在写操作系统的的读取硬盘时遇到问题:
代码:disk.asm
global _read_disk
_read_disk:
push ebp
mov ebp,esp
pusha
xor ecx,ecx
mov ebx,[esp+4];dis_addr
mov cl,[esp+8];counts
mov esi,eax;start LBA
mov dx,0x1f2;设置读取的扇区数
mov al,cl
out dx,al
mov dx,0x1f3
mov eax,esi
out dx,al;0-7bit(LBA)
inc dx
shr eax,8
out dx,al;8-15bit
inc dx
shr eax,8
out dx,al;15-23bit
inc dx
shr ax,8
or al,11100000b
out dx,al;23-27bit and set some disk args
inc dx
mov al,0x20
out dx,al;read disk
.wait:
in al,dx
and al,0x08
cmp al,0x08
jnz .wait
mov di,dx
mov eax,ecx
mov cx,256;每次读取2byte,所以要读取512/2*cl次
mul cx
mov ecx,edx
mov dx,di
.read:
in ax,dx
mov [ebx],ax
add ebx,2
loop .read
popa
mov esp,ebp
pop ebp
ret
编译命令:
nasm syshead.asm -f elf32 -o syshead.o -l syshead.lst
nasm kernelinc/ints.asm -f elf32 -o ints.o
nasm kernelinc/vars.asm -f elf32 -o vars.o
nasm kernelinc/screen.asm -f elf32 -o screen.o
nasm kernelinc/process.asm -f elf32 -o procasm.o
nasm kernelinc/int/clock.asm -f elf32 -o clock.o
nasm kernelinc/disk/disk.asm -f elf32 -o diskasm.o
set gccargs= -std=c11 -m32 -fno-asynchronous-unwind-tables
rem -mno-fp-ret-in-387
rem -mno-red-zone -mgeneral-regs-only -march=i386 -mtune=i386 -mno-80387
gcc %gccargs% -c -g kernel.c -o kernel.o
gcc %gccargs% -c -g kernelinc/interrupt.c -o interrupt.o
gcc %gccargs% -c -g kernelinc/gdtidt.c -o gdtidt.o
gcc %gccargs% -c -g kernelinc/process.c -o process.o
gcc %gccargs% -c -g kernelinc/filesys/fs.c -o fs.o
gcc %gccargs% -c -g kernelinc/disk/disk.c -o disk.o
rem ld -m i386pe -shared -T lds.lds
set head=syshead.o kernel.o
set libs=ints.o vars.o screen.o interrupt.o gdtidt.o process.o procasm.o fs.o clock.o disk.o diskasm.o
ld -m i386pe %head% %libs% -e reload_idt -o sys.elf -Ttext 0x0
没有吧disk.asm编译后的diskasm.o链接进去的时候是好好的,
但是加进去之后,出来的img文件居然缺了一半以上的代码!
不仅少了diskasm.o里面的代码,其他.o文件的
代码也离奇失踪……
加入diskasm.o之前:
代码被拦腰截断:
img就在这里结束了,但是后面还有很多本应该存在的代码……
为什么会这样?是ld的问题还是gcc的问题?
编译输出:
kernel.c: In function 'kernel':
kernel.c:32:2: warning: implicit declaration of function 'read_disk' [-Wimplicit-function-declaration]
32 | read_disk(0,1,0x100000);
| ^~~~~~~~~
boot.bin
setup.bin
sys.bin
已复制 1 个文件。
========================================================================
Bochs x86 Emulator 2.7
Built from SVN snapshot on August 1, 2021
Timestamp: Sun Aug 1 10:07:00 CEST 2021
========================================================================
00000000000i[ ] reading configuration from bochsrc.bxrc
00000000000i[ ] installing win32 module as the Bochs GUI
00000000000i[ ] using log file bochsout.txt
【以下回答由 GPT 生成】
这段代码的问题在于它是汇编代码而不是C语言代码。如果你尝试将它作为C语言代码编译,编译器会以C语言的方式处理这段代码,而不是汇编方式。这样会导致编译器无法正确解析汇编指令并生成可执行的二进制文件。
解决方案是将这段汇编代码保存为一个汇编文件(.asm),然后使用相关的汇编工具来编译生成二进制代码。在Windows环境下,你可以使用MASM(Microsoft Macro Assembler)来编译这段代码。以下是使用MASM的步骤:
安装MASM:你可以从微软的开发者工具包(Microsoft Developer Tools)中下载并安装MASM。
创建汇编文件:打开一个文本编辑器,将你的汇编代码粘贴到其中并保存为一个.asm文件。
编译代码:打开命令提示符(Command Prompt),进入保存有汇编文件的目录。然后使用以下命令编译代码:
ml /c your_asm_file.asm
这将生成一个目标文件(.obj)。
link your_obj_file.obj
这将生成一个可执行文件(.exe)。
现在,你应该有一个可以正确编译的可执行文件了。请注意,以上步骤是针对使用MASM来编译汇编代码的示例。如果你使用的是其他汇编工具,步骤可能会有所不同。
找到问题了:
我最后将几个bin文件合并到一起,命令如下:
copy boot.bin+setup.bin+sys.bin floppy.img /b
这样得到img只有6kb,但是我改成这样:
copy /b boot.bin+setup.bin+sys.bin floppy.img
就完整了。
但是为什么?