x86->2. 尝试做题+bochs虚拟机调试

建立在读完书第六第七章的前提下,此时的我应当有能力写出实现很多简单功能的汇编代码,并在virtualbox上运行。但事实是有点残酷的。

在仿照第七章的书上代码和网上第七章末尾试题答案代码https://blog.csdn.net/sishui_kaki/article/details/132385679

后,我尝试写出以下汇编程序,用以输出data1中数据的负数个数:

         jmp near start

data1 db 0x05,0xff,0x80,0xf0,0x97,0x30
data2 dw 0x90,0xfff0,0xa0,0x1235,0x2f,0xc0,0xc5bc
string db 'n',0x07,'e',0x07,'g',0x07,'a',0x07,'t',0x07,'i',0x07,'v',0x07,'e',0x07,':',0x07
stringend db ' ',0x04



start:
mov ax,0xb800 ;向ES存入文本缓冲区
mov es,ax

cld
mov si,string
mov di,0 ;输出第一行文字
mov cx,(stringend-string)/2
rep movsw






mov cx,0x0006 ;loop 6 times
mov ax,0x7c0 ;存入基地址
mov ds,ax
mov bx,data1 ;偏移地址
xor si,si
xor dx,dx ;清空保存负数个数

judgeneg:
mov al,[bx+si]
inc si
cmp al,10000000b
jl cntrchar

cntrchar:
inc dx
loop judgeneg


loop judgeneg

add dl,0x30
mov di,0+stringend-string
mov [es:di],dl

jmp near $
times 510-($-$$) db 0
db 0x55,0xaa

![](../pics/img 2024-03-14 181836.png)

以及学习了一些介绍x86显存的文章https://blog.csdn.net/longintchar/article/details/70183677

。结果则是,我的虚拟机输出了5个乱码,包含色块和闪烁的字符。

我想,是时候配置一个调试环境了,不然连显存内被写入了什么内容都不知道,更别提写出一个像样的程序了。

bochs配置

很多人使用的linux版,当然像我一样下windows版本也可以。

遵循作者的配置可以比较快地上手,所以我只记录几个遇到的case

  1. PANIC:could not open hard drive image file

​ 这个报错需要找到你的vhd文件同名目录下的.lock文件并删除它,再以管理员权限运行。

  1. 如果使用中出现意外的情况,每次使用都要load你的配置。
  2. virtualbox创建的vhd并不能被作者编写的fixvhd写入文件,也不能被github上的fixvhd写入(相当地没用)

image-20240315000140993

配置成功时可以使用(b 0x7c00)(c)这两个命令,配合你的测试vhd文件。当然使用u/50查看反汇编结果是否和汇编对应更好,这些指令的用处将在下一小节列出(原本也是书上有的)

bochs使用

如果使用过linux的gdb等会有很强的熟悉感,毕竟指令很多都很相似

命令 s b+addr c r n u/Num +addr info q xp/Num+addr
功能 单步执行 断点 持续执行到断点 显示寄存器 完成循环指令 反汇编 查看标志位 退出调试 显示内存地址数据
备注 无法执行循环指令 无法跳过复杂循环 大写对应一,小写零 单位为字,小端序

虽然书中的程序仍然多数都是16位的,但这里的调试程序使用的是32位寄存器,它对16位程序也有着相对完美的兼容性

解决问题

如果你仍然对我失败的程序有兴趣,继续读下去

image-20240315001823741

因为我将loop连续写了两次,cx从第一次6到0的执行结束后,再次步入了新的循环loop,导致了一个相当严重的结果。它将再次循环(0x0000减一是多少次循环?以及执行了这么多次后它还能成功跳出循环吗?)

修改方法之一就是将后一个loop删除,虽然这样右侧会输出一个6,左侧仍然是五个色块和闪烁字符,不符合我预期的结果,但是至少我可以说是理清楚了其中的运行逻辑,并且完整地debug了一次。(色块闪烁问题是字符串输出的设置问题,与循环无关。虽然我暂时不清楚同样的代码为什么会在作者和网上的代码里完美运行)

image-20240315004207350