8086-3-使用bochs調試匯編程序


使用bochs調試匯編程序

前面我們已經搭建好了bochs的環境,並且將我們的匯編程序寫入了硬盤里面,現在我們來看看如何通過bochs來調試我們的程序。

前文:https://www.cnblogs.com/Sna1lGo/p/15695712.html

bochs安裝文件夾

安裝完bochs后,在安裝目錄下我們可以看到有兩個.exe可執行程序:

 

 

bochs.exe就和正常的安裝的虛擬機一樣了,就是直接運行了。

而bochsdbg.exe才是我們要的可調試的虛擬機。

同時可以看到這個文件夾下面有一個docs文件夾,里面包含了bocsh的一些手冊,感興趣的可以讀一下。

進行bochsdbg調試:

首先要啟動bochsdbg虛擬機:

 

 

然后得添加配置文件,前面的章節我們是添加了配置的,但是如果你沒保存,那么很不幸你得再來一次了,需要注意的是保存的配置文件千萬不要修改配置文件的名字。這里由於我保存了的我就直接start了。

加載后是這樣一個界面:

 

 

左邊的display就類似於顯示器了,然后右邊的就是命令行調試窗口,啟動后命令行調試窗口前面顯示的是一系列虛擬機的狀態信息。

bochs會在執行第一條指令的時候停下來,等待我們的操作,也就是這里的命令行調試界面:

 

 

bochs的調試指令可以看bochs的官方文檔上看到:

The Bochs internal debugger (sourceforge.io)

當然它也包含在了我們安裝bochs文件夾的docs文件夾下面。

Next at t=0
(0) [0x0000fffffff0] f000:fff0 (unk. ctxt): jmpf 0xf000:e05b         ; ea5be000f0

0x0000fffffff0 代表真實的物理地址

f000:fff0 是邏輯地址

jmpf 0xf000:e05b 是匯編指令

ea5be000f0 是機器指令

Next at t=0 中的t是執行的指令個數,也叫做內部時鍾

注:細心的朋友可能會發現,這里的f000:fff0的邏輯運算是無法計算得到0x0000fffffff0地址的,這個只會在處理器剛啟動的時候發生,然后后面會解釋,這里先暫時就這個樣子。

肯定有同學會奇怪啊,前面我們說了8086啟動的第一條指令是jmp FFFF:0000啊,這里怎么不一樣,那說明這個cpu不是8086呀。哈哈。

我們把這個調試界面往前翻一下,查看前面的狀態信息可以看到:

 

 

這里的CPU configuration也就是CPU的配置信息是x86-64的,是intel的支持x86的CPU並不是8086CPU。

 

這里我們可以先單步執行看看內容,這里是所有的執行指令:

  c                           continue executing
cont
continue

s     [count]               execute count instructions, default is 1
step [count]

s     [cpu] [count]         for SMP simulation, execute count instructions on cpu, default is 1
step [cpu] [count]

s     all [count]           for SMP simulation, execute count instructions on all cpus
step all [count]

Ctrl-C                      stop execution, and return to command line prompt
Ctrl-D                      if at empty line on command line, exit

q                           quit debugger and execution
quit
 exit

可以采用s來單步執行,默認是只執行一條,就到了這里:

 

 

可以看到這個地址區域,是滿足前面我們將的cpu地址分區的BIOS地址區域的在F0000~FFFFF之間。

那么如果我們想直接到我們寫的主引導扇區里面怎么辦呢,我們可以給主引導扇區的第一條代碼打一個斷點,這里是所有的斷點指令:

NOTE: The format of 'seg', 'off', and 'addr' in these descriptions,
      are as follows. I don't have any way to set the current radix.

      hexidecimal:   0xcdef0123
      decimal:        123456789
      octal:          01234567

vbreak seg:off             Set a virtual address instruction breakpoint
vb     seg:off

vbreak seg:off if "expr"   Set a conditional virtual address instruction breakpoint
vb     seg:off if "expr"

lbreak addr                 Set a linear address instruction breakpoint
lb     addr

lbreak addr if "expr"       Set a conditional linear address instruction breakpoint
lb     addr if "expr"

pbreak [*] addr             Set a physical address instruction breakpoint
pb     [*] addr             (the '*' is optional for GDB compatibility)
break [*] addr
b     [*] addr

pbreak [*] addr if "expr"   Set a conditional physical address instruction breakpoint
pb     [*] addr if "expr"   (the '*' is optional for GDB compatibility)
break [*] addr if "expr"
b     [*] addr if "expr"

info break                 Display state of all current breakpoints
bpe   n                   Enable a breakpoint
bpd   n                   Disable a breakpoint
delete n                   Delete a breakpoint
del   n
d     n

那么打斷點肯定是不能像vs調試一樣直接給代碼打上斷點然后直接調試就完事了,在cpu的層面是直接給地址打斷點,執行到該處就直接停下來。前面的博客我們學習到,CPU會把主引導扇區的內容加載到內存的 0000:7c00處,那么我們直接給這個地址打個斷點然后運行到這個地址就停下來不就行了嗎。

 

 

b 0x7c00

解釋一下這條命令,上面我寫了所有的斷點指令,然后單獨的 b 后面是跟着addr,然后邏輯地址的0000:7c00就是物理地址的 7c00,所以我這樣使用是沒問題的。

然后我們可以輸入執行指令,來直接執行到設置的斷點處:

 

 

這里就是我們前面寫好的匯編代碼了。

然后采用s指令單步調試來把我們的代碼都執行完:

 

 

好這里就執行完了,然后可以查看一下寄存器,看看ax,dx是不是我們設想的內容。

以下是查看bochs虛擬機信息的所有指令:

  r|reg|regs|registers         List of CPU integer registers and their contents
fp|fpu                       List of all FPU registers and their contents
mmx                         List of all MMX registers and their contents
sse|xmm                     List of all SSE registers and their contents
ymm                         List of all AVX registers and their contents
sreg                         Show segment registers and their contents
dreg                         Show debug registers and their contents
creg                         Show control registers and their contents

info cpu                     List of all CPU registers and their contents
info eflags                 Show decoded EFLAGS register
info break                   Information about current breakpoint status
info tab                     Show paging address translation
info device                 Show state of the specified device

 

 

可以看到ax和dx確實是我們想要的內容,0x00F0和0x00c0。

這樣就很完美了。

 

由於我們這次寫的匯編代碼很簡單,所以就這么幾條就執行完了。

可以使用退出指令來直接退出該bochs虛擬機了:

q                           quit debugger and execution
quit
exit

 

 

這樣摁完Enter回車就可以美美噠結束了。

小結

采用原原本本的通過cpu來執行匯編代碼的方式雖然比較繁瑣,但是逼格很高,哈哈,至少我是這樣認為的。

總結一下流程:

先寫好匯編代碼,然后編譯,編譯好之后,和512個字節進行比對,不夠的要填充,填充的時候注意最后兩個字節的內容必須為55和AA,然后將其寫入硬盤里。再啟動bochs虛擬機給系統主引導扇區的地址打斷點,然后執行continue運行,會停止到斷點處,就可以進行對我們自己的匯編語言代碼進行調試了。而且是繞過了Windows\linux這樣的大型操作系統,這多酷。然后如果調試遇到指令問題就查看bochs的文檔就可以了。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM