tiny-os
tiny-os copied to clipboard
P87, b 0x900 我把 call.bin 放在了内存 0x900 处,所以在此处设置断点,没告诉怎么把call.bin 放在了内存 0x900 处?
您好! 书中第87页,没有告诉如何把call.bin放到0x900 处? 麻烦给个简单的方法.谢谢!
我解决了这个问题: 核心: 需要写汇编程序自己搬运代码到0x900去.
验证call,ret实验
A. 创建项目文件夹
# 创建文件夹example_chap03_nasm_002/
mkdir -p ~/linux_sources/example_chap03_nasm_002/
==========================================
B. call near近调用例子
B.1 编写1call.S代码
内容:
section call_test vstart=0x900
call near near_proc
jmp $
addr dd 4
near_proc:
mov ax, 0x1234
ret
==========================================
B.2 使用Bochs检查机器码
B.2.1 创建mbr.S代码
内容:
SECTION MBR vstart=0x7c00
mov eax, 0x2 ; 起始扇区lba地址,从间隔第二个扇区开始
mov bx, 0x900 ; 写入的地址
mov cx, 1 ; 待读入的扇区数,读取1个扇区内容
call rd_disk_m_16 ; 以下读取程序的起始部分(一个扇区)
jmp 0x900
;-------------------------------------------------------------------------------
;功能: 读取硬盘n个扇区
rd_disk_m_16:
;-------------------------------------------------------------------------------
; eax=LBA扇区号
; ebx=将数据写入的内存地址
; ecx=读入的扇区数
mov esi,eax ; 备份eax
mov di,cx ; 备份cx
; 读写硬盘:
; 第1步: 设置要读取的扇区数
mov dx,0x1f2
mov al,cl
out dx,al ; 读取的扇区数
mov eax,esi ; 恢复ax
; 第2步: 将LBA地址存入0x1f3 ~ 0x1f6
; LBA地址7~0位写入端口0x1f3
mov dx,0x1f3
out dx,al
; LBA地址15~8位写入端口0x1f4
mov cl,8
shr eax,cl
mov dx,0x1f4
out dx,al
; LBA地址23~16位写入端口0x1f5
shr eax,cl
mov dx,0x1f5
out dx,al
shr eax,cl
and al,0x0f ; lba第24~27位
or al,0xe0 ; 设置7~4位为1110,表示lba模式
mov dx,0x1f6
out dx,al
; 第3步: 向0x1f7端口写入读命令,0x20
mov dx,0x1f7
mov al,0x20
out dx,al
; 第4步: 检测硬盘状态
.not_ready:
;同一端口,写时表示写入命令字,读时表示读入硬盘状态
nop
in al,dx
and al,0x88 ; 第4位为1表示硬盘控制器已准备好数据传输,第7位为1表示硬盘忙
cmp al,0x08
jnz .not_ready ; 若未准备好,继续等.
; 第5步: 从0x1f0端口读数据
mov ax, di
mov dx, 256
mul dx
mov cx, ax ; di为要读取的扇区数,一个扇区有512字节,每次读入一个字,
; 共需di*512/2次,所以di*256
mov dx, 0x1f0
.go_on_read:
in ax,dx
mov [bx],ax
add bx,2
loop .go_on_read
ret
times 510-($-$$) db 0
db 0x55,0xaa
==========================================
B.2.2 编译
cd ~/linux_sources/example_chap03_nasm_002/
rm -rf *.bin *.lock
nasm -o 1call.bin 1call.S
nasm -o mbr.bin mbr.S
# 使用bximage命令生成虚拟硬盘
bximage --> 1 --> hd --> flat --> 60 --> hd60M.img
# 使用dd命令将操作系统写入硬盘镜像(写入数据到镜像中)
cd ~/linux_sources/example_chap03_nasm_002/
dd if=mbr.bin of=hd60M.img bs=512 count=1 conv=notrunc
dd if=1call.bin of=hd60M.img bs=512 count=1 seek=2 conv=notrunc
==========================================
B.2.3 配置bochs配置文件
cd ~/linux_sources/example_chap03_nasm_002/
vi bochsrc_1call.disk
内容:
# Bochs配置文件
# 机器内存: 32MB
megs: 32
# 启动方式
boot: disk
# 关闭鼠标
mouse: enabled=0
# 硬盘设置
ata0: enabled=1, ioaddr1=0x1f0, ioaddr2=0x3f0, irq=14
ata0-master: type=disk, path="hd60M.img", mode=flat, cylinders=121, heads=16, spt=63
==========================================
B.2.4 测试
# 启动bochs
# Applications-->System Tools-->Terminal
cd ~/linux_sources/example_chap03_nasm_002/
rm -rf *.lock
bochs -f bochsrc_1call.disk
--> 6
b 0x900
c
到0x900后
u 0x900 0x920
输出:
00000900: ( ): call .+6 ; e80600
00000903: ( ): jmp .-2 ; ebfe
00000905: ( ): add al, 0x00 ; 0400
00000907: ( ): add byte ptr ds:[bx+si], al ; 0000
00000909: ( ): mov ax, 0x1234 ; b83412
0000090c: ( ): ret ; c3
...
这是期望的结果.
Ctrl+C-->quit
就退出Bochs环境了.