跳至主要內容

ComputerSystems

LincZero大约 4 分钟

ComputerSystems

目录

汇编调试

调试汇编程序

Bochs虚拟机(调试神器)

官网:http://bochs.sourceforge.net

下载地址:https://sourceforge.net/projects/bochs/files/bochs/2.6.11/

简单介绍:官网左下侧是使用手册,手册齐全、功能丰富、软件迷你仅仅5MB

使用:下载安装完成后有两个exe:bochs.exe和bochsdbg.exe,调试汇编程序时主要使用到的是后者

调试过程

配置部分

  1. 将二进制写入虚拟硬盘

    用FixVhdw程序将bin写入VHD后会告诉你程序写在了哪个物理空间

    提示信息:

    虚拟硬盘: D:...\Worksapce_VirtualBox\AssemblyTest\AssemblyTest\AssemblyTest.vhd VHD规范的原始创建者标识: conectix 创建此文件的程序:vbox 创建此文件的程序版本:06.01 该虚拟磁盘创建于 2021-11-08 13:31:44。 481个柱面;4个磁头;每磁道有17个扇区。 总容量为 16 MB(兆字节)。 该磁盘为固定磁盘(容量固定,文件大小不变)。

  2. 配置FixVhdw,当然这步不是必须的,只是为了方便

    • 在VBox路径名的选项中,选择VirtualBox安装目录中的VirtualBox.exe,以方便快速执行VBox虚拟机
    • 在Bochs路径名的选项中,选择Bochs的安装路径下的bochsdbg.exe,以方便快速执行Bochs虚拟机
    • 在其他程序路径名的选项中,选择Bochs的安装路径下的bochs.exe,该程序不带Debug功能
  3. 点击写入并执行Bochs虚拟机

    • 初次启动时需要进行配置
    • 选择CD通道:中间的Disk&Boot > 左侧的Edit > 弹出框 > ATA Channel 0 > First HD/CD on Channel
      • Type of ATA device下拉框:disk (默认none)
      • Path or physical device name:选择对应的虚拟磁盘.vhd文件 (文件筛选要All files)
      • 填写磁盘物理位置(需要填写之前在FixVhdw中提示的内容),demo中分别是481-4-17
        • Cylinders 柱面
        • Heads 磁头
        • Sector per track 每道扇区
    • Boot配置:Boot Options
      • Boot drive #1:disk (默认floopy)
    • 最后选择OK完成设置。可以将该配置保存为一个文件,不用每次都设置:点击左侧的Save按钮即可保存,若需加载则点击Load按钮
    • 点击右侧的Start按钮运行debug用虚拟机,弹出黑框表示已进入调试状态。大黑框是调试窗口,新黑框是输出窗口

调试命令

常用命令

  • s:单步调试

  • s 200:s后面加数字,表示进行多少次单步调试

  • b:打断点,后跟内存地址,例如:b 0x7c00,会直接跳转到该位置

  • c:contine,继续执行

  • q:quit,退出调试,按两次Enter完全退出。不能点叉号关闭窗口,不然会导致你下一次不能运行

  • r:查看所有通用寄存器的内容(除了通用寄存器外还显示控制寄存器 (IP和EFLAGS) )

    ; 可以看到每个寄存器都是16位的
    ; 若单步调试运行`mov ax, 0xb800`后,第一行会变为:
    ; rax: 00000000_0000b800
    rax: 00000000_0000aa55
    rbx: 00000000_00000000
    rcx: 00000000_00090000
    rdx: 00000000_00000080
    rsp: 00000000_0000ffd6
    rbp: 00000000_00000000
    rsi: 00000000_000e0000
    rdi: 00000000_0000ffac
    r8 : 00000000_00000000
    r9 : 00000000_00000000
    r10: 00000000_00000000
    r11: 00000000_00000000
    r12: 00000000_00000000
    r13: 00000000_00000000
    r14: 00000000_00000000
    r15: 00000000_00000000
    ; 指令指针。这里的rip是7c00
    rip: 00000000_00007c00
    ; 标志寄存器。eflags是存储标志位的,比如最后的可以用来存储进位和错位信息的cf,如果是小写则它是0,如果是大写那么它是1
    eflags 0x00000082: id vip vif ac vm rf nt IOPL=0 of df if tf SF zf af pf cf
    
  • sreg:查看段寄存器的内容(前4还是6个是段寄存器,后面的我也不指导是什么)

    es:0x0000, dh=0x00009300, dl=0x0000ffff, valid=1	; 附加段
            Data segment, base=0x00000000, limit=0x0000ffff, Read/Write, Accessed
    cs:0x0000, dh=0x00009300, dl=0x0000ffff, valid=1	; 代码段
            Data segment, base=0x00000000, limit=0x0000ffff, Read/Write, Accessed
    ss:0x0000, dh=0x00009300, dl=0x0000ffff, valid=7	; 堆栈段
            Data segment, base=0x00000000, limit=0x0000ffff, Read/Write, Accessed
    ds:0x0000, dh=0x00009300, dl=0x0000ffff, valid=1	; 数据段
            Data segment, base=0x00000000, limit=0x0000ffff, Read/Write, Accessed
    fs:0x0000, dh=0x00009300, dl=0x0000ffff, valid=1	; (FS和GS寄存器无专用名称)
            Data segment, base=0x00000000, limit=0x0000ffff, Read/Write, Accessed
    gs:0x0000, dh=0x00009300, dl=0x0000ffff, valid=1	; (FS和GS寄存器无专用名称)
            Data segment, base=0x00000000, limit=0x0000ffff, Read/Write, Accessed
    ldtr:0x0000, dh=0x00008200, dl=0x0000ffff, valid=1
    tr:0x0000, dh=0x00008b00, dl=0x0000ffff, valid=1
    gdtr:base=0x00000000000f9ad7, limit=0x30
    idtr:base=0x0000000000000000, limit=0x3ff
    
  • xp /nuf addr:查看物理内存,n=查看多少个单位,u=单位,u可以是b/h/w/g (1/2/4/8字节),例如:xp /1wx 0x7c0f1

正式调试部分

调试过程

; 跳转到地址e05b,e05b是BIOS程序的入口
Next at t=0
(0) [0x0000fffffff0] f000:fff0 (unk. ctxt): jmpf 0xf000:e05b          ; ea5be000f0

> s
Next at t=1
(0) [0x0000000fe05b] f000:e05b (unk. ctxt): xor ax, ax                ; 31c0

> s
Next at t=2
(0) [0x0000000fe05d] f000:e05d (unk. ctxt): out 0x0d, al              ; e60d

> s
Next at t=3
(0) [0x0000000fe05f] f000:e05f (unk. ctxt): out 0xda, al              ; e6da

; b:打断点并跳转到0x7c00的位置
; c:contine,继续执行
; 此时输出窗口开始显示文本
; 此时可以看到07c001的汇编指令:mov ax, 0xb800,后面跟着的那个是实际的机器码
> b 0x7c00
> c
Next at t=17178871
(0) [0x000000007c00] 0000:7c00 (unk. ctxt): mov ax, 0xb800            ; b800b8

; 此时s可以一直单步调试汇编代码的部分
> s
; ...

> q

nasm技巧

nasm -f bin start.asm -o start.bin -l start.lst
# 【技巧】
# -l:然后后面再加一个.lst扩展名的文件,可以生成一个包括汇编地址、代码以及机器码的文件。可以方便用来调试