最近突然迷恋上了汇编,其实我一直都对汇编很向往,但是汇编对我不理不采,苦于找不到好的精通资料,一直在这门功课上亏欠。
最近看到 李忠老师 的《x86汇编语言 从实模式到保护模式》,发现人督二脉有被打通的预兆。哈哈, 这里预祝一下自己马到成功,也感谢下李老师。
这本书对于我这种有点计算机基础的人来说,有很好的带入性,下面是我的阅读笔记。
- 例子4-2
mov ax, 0xb800
mov ds, ax
mov [0x00],'a'
mov [0x02],'s'
mov [0x04],'m'
jmp $
(有点小遗憾,好像汇编在csdn的markdown没有支持高亮,我目前用的avrasm(参考 ) , 如果有小伙伴发现了汇编高亮配置了,请给我留言,谢谢)
编译的时候的报错信息:
4-2.asm:3: error: operation size not specified
4-2.asm:4: error: operation size not specified
4-2.asm:5: error: operation size not specified
出这个问题不知道是不是64位环境的原因,解决方案[参考]:
修改代码,在地址前加类型,如下所示:
mov ax, 0xb800
mov ds, ax
mov dword [0x00],'a'
mov dword [0x02],'s'
mov dword [0x04],'m'
jmp $
不知道是不是我的操作问题,运行的时候没有出现预料中的 ‘asm’, 相关字符,有点小遗憾,只有接着走,看后面有没有原因。
ps: 找到原因了,原来是第一个扇区是引导扇区,最后两个要为 0x55,0xaa, 否者会被判别为无效。
-
在本书中,李忠老师推荐了bochs模拟器软件,然后还说了随书资料中有安装和配置说明,我发现李忠老师用的是win的版本,而我是ubuntu的linux。
我下载了软件编译出来没有bochsdbg这个程序,然后在博客上看到,要用如下命令编译才有debug版本。
./configure --enable-debugger --enable-disasm
然后make和sudo make install
我的运行配置如下(其中一些路径,需要自己根据实际情况进行替换):# #Bochs运行中使用的内存,设置为32M megs: 32 #设置真实机器的BIOS和VGA BIOS #修改成你们对应的地址 romimage: file="/media/lhpc04/869762e7-5cfb-40a4-82aa-c0477c0fd3c2/program/bochs-2.6.9/bios/BIOS-bochs-latest" vgaromimage: file="/media/lhpc04/869762e7-5cfb-40a4-82aa-c0477c0fd3c2/program/bochs-2.6.9/bios/VGABIOS-lgpl-latest" #设置Bochs所使用的磁盘 #设置启动盘符 boot: disk #设置日志文件的输出 log: bochs.out #开启或关闭某些功能,修改成你们对应的地址 # mouse: enabled=0 keyboard: keymap="gui/keymaps/x11-pc-us.map" #硬盘设置 # ata0: ioaddr1=0x1f0, ioaddr2=0x3f0, irq=14 ata0-master: type=disk, path="~/workspace2/books/硬件/x86汇编语言 从实模式到保护模式/booktool/LEECHUNG.vhd", mode=vpc, cylinders=1003, heads=12, spt=17 #增加bochs对gdb的支持,我们在这里不使用,所以注释掉了 #gdbstub: port=1234, text_base=0, data_base=0, bss_base=0
上面配置文件的文件名为bochsrc,所以我执行命令:
bochs -f bochsrc
运行的情况如下
还是有一个大坑,这里执行我们的命令其实要先执行一大堆系统带的命令,我开始的时候摸不到头脑,不晓得怎么调试,不过还是有方法的。
在启动的时候先加断点,然后运行命令,命令和截图如下:
<bochs:1> b 0x7c0:0
<bochs:2> c
可以继续调试和执行我们的命令了
参考:
- 学习笔记 |《ORANGE’S:一个操作系统的实现》| (一) Ubuntu - 16.04 bochs安装与配置
- bochs简单使用
- Bochs常用调试命令 (感觉有的命令被更新了,可以将就看看,详细的可以用h|help查看)
显存寄存器颜色
K | R | G | B | I | R | G | B |
---|
R | G | B | 背景K=0不闪烁,K=1闪烁 | 前景色I=0 | 背景色I=1 |
---|---|---|---|---|---|
0 | 0 | 0 | 黑 | 黑 | 灰 |
0 | 0 | 1 | 蓝 | 蓝 | 浅蓝 |
0 | 1 | 0 | 绿 | 绿 | 浅绿 |
0 | 1 | 1 | 青 | 青 | 浅青 |
1 | 0 | 0 | 红 | 红 | 浅红 |
1 | 0 | 1 | 品(洋)红 | 品(洋)红 | 浅品(洋)红 |
1 | 1 | 0 | 棕 | 棕 | 浅棕 |
1 | 1 | 1 | 白 | 白 | 浅白 |
15 | 14 | 13 | 12 | 11 | 10 | 9 | 8 | 7 | 6 | 5 | 4 | 3 | 2 | 1 |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
OF | DF | IF | TF | SF | ZF | AF | PF | CF | ||||||
溢出标志位 | 方向标志 | 符号位 | 零标志 | 奇偶标志位 | 进位标志位 |
指令 | 影响描述 |
---|---|
add | OF, SF, ZF, AF, CF 和PF 的状态依计算结果而定。 |
cbw | 不影响任何标志位 |
cld | DF=0, CF,OF,ZF,SF,AF和PF未定义,未定义的意思是到目前为止还不打算让该指令影响到这些标志,因此,不要在程序中依赖这些标志 |
cwd | 不影响任何标志位 |
dec | CF标志不受影响,因为该指令通常在程序中用于循环计数,而且在循环体内通常有依赖CF标志的指令, 故不希望它打扰CF标志,对OF,SF,ZF,AF和PF的影响依计算结果而定。 |
div/idiv | 对CF, OF, SF, ZF, AF和PF的影响未定义。 |
inc | CF标志不受影响, 对OF,SF,ZF,AF和PF的影响依计算结果而定。 |
mov/movs | 这类指令不影响任何指令。 |
neg | 如果操作数为0, 则CF=0, 否则CF=1;对OF,SF,ZF,AF和PF的影响依计算结果而定。 |
std | DF=1, 不影响其他标志位。 |
sub | 对OF,SF,ZF,AF,PF和CF的影响依计算结果而定。 |
cmp | 对OF,SF,ZF,AF,PF和CF的影响依计算结果而定。 |
xor | OF=0,CF=0; 对SF,ZF和PF依计算结果而定; 对AF的影响未定义。 |
or | OF和CF位被清零,SF,ZF,PF位的状态以计算结果而定,AF为的状态未定义。 |
add | OF和CF位被清零,SF,ZF,PF位的状态以计算结果而定,AF为的状态未定义。 |
push | 不影响任何标志位 |
序号 | 指令 | 描述 |
---|---|---|
1 | jns/js | s标志为1的时候js跳转, s为0的时候jns跳转 |
2 | jnz/jz | z标志为1的时候jz跳转, z为0的时候jnz跳转 |
3 | jno/jo | o标志为1的时候jo跳转, o为0的时候jno跳转 |
4 | jnc/jc | c标志为1的时候jc跳转, c为0的时候jnc跳转 |
5 | jnp/jp | p标志为1的时候jp跳转, p为0的时候jnp跳转 |
比较及命令
比较 | 命令 |
---|---|
等于 | je |
不等于 | jne |
大于 | jg |
大于等于 | jge |
不大于 | jng |
不大于等于 | jnge |
小于 | jl |
小于等于 | jle |
不小于 | jnl |
不小于等于 | jnle |
高于 | ja |
高于等于 | jae |
不高于 | jna |
不高于等于 | jnae |
低于 | jb |
低于等于 | jbe |
不低于 | jnb |
不低于等于 | jnbe |
校验为偶 | jpe |
校验为奇 | jpo |
jcxz: cx寄存器为0的时候转移。
$ :当前行的汇编地址
$$ :当前段的起始地址
在8086处理器上, 如果要用寄存器来提供偏移地址,只能使用 BX, SI, DI, BP, 不能使用SP, IP, AX, CX, DX 寄存器。
AX - 累加器
CX - 计数器
DX - 数据寄存器,用于外设之间进行数据传送
SI - 源索引寄存器
DI - 目标索引寄存器,用于数据传送操作, movsb, movsw
在intel8086处理器只允许以下几种基址寄存器和变址寄存器的组合
[bx+si]
[bx+di]
[bp+si]
[bp+di]
可以用于任何带有内存操作数的指令中,其他的都是非法的
进位判断方法:加减时最高位产生进位或借位,代表结果超出无符号数的范围,单字节就是0~255;
溢出判断方法:加减时最高位和次高位中有且仅有一个产生进位或借位,代表结果超出有符号数的范围,单字节就是-128~127;
寻址方式:
- 寄存器寻址
- 立即寻址
- 内存寻 — 根本就是指出内存的位置,下面是指出的方式
- 直接寻址
- 基址寻址 , 用到了基址寄存器BP, BX
- 变址寻址, 用到了变址寄存器SI,DI
- 基址变址寻址 , 变址和基址寄存器都用到了
不更新了,扎起眨巴的太多了,这是1-7章的内容,后面新起一篇作为后面的学习笔记。