跳至主要內容

ComputerSystems

LincZero大约 3 分钟

ComputerSystems

目录

汇编代码

HelloWorld

HelloWorld.asm

; mov:	是move的缩写,二元指令
; a1:	目的。ax是CPU内的一个通用寄存器
; a2:	源。0b800h是显存的一个地址,h表示hex,也可写作0x0b800
mov ax, 0b800h

; 指定数据段基准地址
; a1:	目的,ds是数据端开头
; a2:	源。ax是一个通用寄存器,目前存储着0x0b800h
mov ds, ax

; 将字符放到指定的内存空间
; 这里每两个字符之间相隔2个字节而不是1个字节是因为在彩色文本空间(0b800h)中还有1字节是属性字节(这里不填即默认的黑底白字)
; mov:	move
; byte:	指定传送数据的大小为1字节
; 0x00:	地址。这里的0x00不是BIOS占用的地址,这里的0x00是基于前面0b800h的内存偏移后的0x00
; 'H':	内容
mov byte [0x00],'H'
mov byte [0x02],'e'
mov byte [0x04],'l'
mov byte [0x06],'l'
mov byte [0x08],'o'
mov byte [0x0a],','
mov byte [0x0c],'W'
mov byte [0x0e],'o'
mov byte [0x10],'r'
mov byte [0x12],'l'
mov byte [0x14],'d'

; 标定当前位置
; jmp:	修改IP。跳到jmp所在的位置
; $:	标定当前位置
jmp $

; 将jmp $到0x55之间的位置全部填0
; 510:	MBR分区是512字节,减2表示减去0x55,0xaa两个字节
; $$:	程序起始位置
; $:	jmp所在位置
; $-$$:	从程序开头到jmp的位置一共有多少个字节
; 510-($-$$):	应该填充0的个数
times 510-($-$$) db 0

; 0x55,0xaa:	MBR分区最后的标志位
db 0x55,0xaa

原理补充 —— 显卡的彩色文本模式

前面的0b800h就是彩色文本模式对应的寻址范围

  • 汇编原理

    • 当将数据写入这些地址空间,实际上是写入到显卡的显存里,然后显示器从显存里将数据取走,然后显示走屏幕上
  • 显卡模式

    • 显卡是支持文字模式和图形模式的,其中文字模式还支持黑白和彩色两种

    • 彩色图形:[暂略]

    • 文字模式:文字模式会把显示器的整个区域分割成25行,每行80个字符(编程建议一行不超过80个字符的由来) 工程师不用每次都操作像素

      • 黑白文本:基本不会有人用了

      • 彩色文本:字符可以有多种颜色,不仅仅发送ASCII码,还要指定一个属性字节,例如发送0x4107是黑底白字

      • 属性字节

        数字符号作用
        7K是否闪烁
        6R背景色 - 红
        5G背景色 - 绿
        4B背景色 - 蓝
        3I是否高亮
        2R前景色 - 红
        1G前景色 - 绿
        0B前景色 - 蓝

一些符号

注释;

分号;

当前汇编地址$

jmp $就是在原地打转,不让程序直接退出,等同于wula: jmp wula

程序开头汇编地址$$

equ 常量声明 (汇编器命令)

equ:声明常量。原理:编译时会将equ常量替换为具体地址。反编译不可回溯

举例:

NUL equ 0x00			; 空
SETCHAR equ 0x07		; 设置字符属性
VIDEOMEM equ 0xb800		; 显卡内存
STRINGLEN equ 0xffff	; 字符串长度(循环次数)