[书]x86汇编语言:从实模式到保护模式 -- 第六、七章 编写主引导扇区代码

第六章 编写主引导扇区代码(启动时显示文字:Label offset:)

PART 1 >> 用VirtualBox显示最终效果

1.1 汇编

启用nasm的工具“nasm-shell”,执行命令“nasm test.asm -o test.bin”

1.2 写入虚拟磁盘文件

启用本书配套工具“fixvhdwr.exe”,将汇编得到的test.bin文件写入VirtualBox的虚拟磁盘文件test.vhd

1.3 执行

启用VirtualBox,最终显示的偏移地址为29(十进制)

 

===================================================================================================

PART 2 >> 用Bochs调试

2.1 配置Bochs

参考本书相关指引,得到配置文件“bochsrc.bxrc”

2.2 启用调试

1)ROM-BIOS,0xf000:0xe05b

物理地址0x07c00:如果计算机的设置是从硬盘启动,ROM-BIOS将读取硬盘主引导扇区的内容并加载到内存0x0000:0x7c00处

2)启用Bochs工具bochsdbg.exe

对应汇编源码可看到需要显示的偏移地址为0x001d(十六进制),即29(十进制)

 

===================================================================================================

PART 3 >> 汇编源码


    jmp near start

; 字符串"Label offset:",显示属性0x07(黑底白字)
mytext db 'L',0x07,'a',0x07,'b',0x07,'e',0x07,'l',0x07,' ',0x07,'o',0x07,\
          'f',0x07,'f',0x07,'s',0x07,'e',0x07,'t',0x07,':',0x07
    
mynumber db 0, 0, 0, 0, 0

start:
    ; 若从硬盘启动,BIOS读取主引导扇区并加载到内存0x0000:0x7c00,即0x07c00
    mov ax, 0x7c0   ; 此处技巧性地将0x07c00看作0x07c0:0x0000
    mov ds, ax
    
    mov ax, 0xb800  ; 显卡对应的物理地址空间: 0xb8000 ~ 0xbffff
    mov es, ax
    
    ; 传送指令: movsb movsw
    ; 源地址ds:si, 目的地址es:di
    ; 传送方向: cld正向,std反向
    mov si, mytext
    mov di, 0
    mov cx, (mynumber-mytext)/2
    cld
    rep movsw   ; rep重复执行,次数为CX
    
    ; div, 除以16位的二进制数
    ; 被除数(高16位dx, 低16位ax), 商ax, 余数dx
    mov ax, mynumber    ; 要显示的数据
    mov si, 10  ; 除数
    mov cx, 5   ; loop循环次数
    mov bx, ax  ; 偏移地址
digit:
    xor dx, dx
    div si
    mov [bx], dl ; 依次将mynumber十进制的各个位数存至[ds:bx]
    inc bx
    loop digit
    
    mov bx, mynumber
    mov si, 4
show:
    mov al, [bx+si]
    add al, 48      ; 将mynumber十进制的各个位数转为字符型
    mov ah, 0x04    ; 显示属性0x04(黑底红字)
    mov [es:di], ax ; 移至显存映射的内存空间
    add di, 2
    dec si          ; 影响符号位SF(Sign Flag)
    jns show        ; jns, SF=0跳转    
    
    mov al, 'D'     ; 黑底白字显示字符'D'
    mov ah, 0x07
    mov [es:di], ax
    
    jmp near $      ; $, 当前行的汇编地址
                    ; $$, 当前汇编节(段)的起始汇编地址
    times 510-($-$$) db 0
    db 0x55, 0xaa
  

 

===================================================================================================

第六章 初识堆栈(求和1~100,并显示)

PART 1 >> 用VirtualBox显示最终效果

 

===================================================================================================

PART 3 >> 汇编源码

; DATE: 20191207

jmp near start

message db "1+2+3+...+100="

start:
    ; 若从硬盘启动,BIOS读取主引导扇区并加载到内存0x0000:0x7c00,即0x07c00
    ; 0x0000:0x7c00 等同于 0x07c0:0x0000
    mov ax, 0x07c0
    mov ds, ax

    ; 显卡对应的物理地址空间: 0xb8000 ~ 0xbffff
    mov ax, 0xb800
    mov es, ax
    
    mov si, message
    mov di, 0
    mov cx, start-message
show_message:
    mov al, [si]
    mov ah, 0x07    ; 显示属性0x07(黑底白字)
    mov [es:di], ax
    inc si
    add di, 2
    loop show_message ; cx为循环计数
    
    xor ax, ax
    mov cx, 1
sum:
    add ax, cx
    inc cx
    cmp cx, 100
    jle sum
    
    ; 设置堆栈段的段基地址
    xor cx, cx
    mov ss, cx
    mov sp, cx

    mov bx, 10
digit_sum:
    xor dx, dx
    div bx
    or dl, 0x30     ; 加48将数字转为字符型
    mov dh, 0x07    ; 显示属性0x07(黑底白字)
    push dx
    inc cx
    cmp ax, 0
    jne digit_sum
    
show_sum:
    pop word [es:di]
    add di, 2
    loop show_sum   ; cx为循环计数
    
    jmp near $
    
    times 510-($-$$) db 0
    db 0x55, 0xaa
    

 

 

 

 

 

 

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值