汇编读取硬盘
汇编读取硬盘目标:把指定数据从硬盘里读取出来,保存到指定内存,把这些数据输出到屏幕
端口本质是寄存器的代号,读写只能用in/out指令,如显卡,硬盘都有自己的寄存器,CPU读写不同的端口,实质上是在读写不同的寄存器。
计算机的主硬盘分配了8个端口,0x1f0~0x1f7
读写硬盘CHS(Cylinders Heads Sectors),需要把磁头、柱面和扇区信息都传递下去。现在已经不用了
LBA(Logical Block Addressing),逻辑块寻址。
in-读出指令in dest目的(al/ax) source源(dx/imm8)
源可以是8位立即数或者dx寄存器,使用8位立即数只能访问0~255端口,存在局限性。而使用dx寄存器则可以访问0~65535端口
out-写入指令out dest目的(dx/imm8) source源(al/ax)
LBA28用28位来标记硬盘的逻辑扇区号,总共2^28个扇区,每个扇区512字节。也就是说可以寻编128GB的硬盘
要读取硬盘的第一步,是告诉硬盘要读取几个扇区,这个数值要写到0x1f ...
更优雅的打印字符串
更优雅的打印字符串目标:给定一个以0x00结尾的字符串在内存中的起始地址,通过调用一个函数,把整个字符串输出到屏幕上。
ds和es是段寄存器,si和di是变址寄存器
通过段寄存器DS以及源索引寄存器SI来保存字符串的起始地址,即DS:SI,而SI指向第一个字符出现的位置,取出一个字符SI就加1。通过段寄存器ES以及目标索引寄存器DI,保存写入的目标地址,也就是显存的地址,ES的值位0xb800,DI寄存器的初始值位0x0000,写入一个字节就加1, 通过循环将DS:SI指向的字符串依次取出,并写入到ES:DI指向的目标地址,直到遇到0x00结束循环
EFLAGS寄存器第0位CF位,进位标志
第2位PF位,偶数标志位,当计算结果是偶数时,PF会被置1
第6位是ZF位,Zero Flag,零标志位,独立结果为0时,ZF会被置1
第7位是SF位,也就是符号位,比如减法结果为负值,他就会被置1
第11位是OF位,也是溢出位,当计算结果存在溢出时,它会被置为1
标志位的用法,要结合条件转移指令使用
JCC-条件转移指令jz Jump if zero(ZF=1)
jnz Ju ...
X86汇编的乘除法以及栈的定义使用
X86汇编的乘除法以及栈的定义使用寄存器向下兼容,保留了ax,bx等寄存器
乘除法乘法:mul + reg/mem
除法:div + reg/mem
它们只有一个操作数,所以会使用特定的寄存器,来保存另外一个参与计算的数
如果是8位乘8位的乘法,乘积的高8位保存在ah寄存器,低8位保存在al寄存器;如果是16位的乘法,高16位存在dx寄存器,低16位存在ax寄存器;
乘法的结果也会影响CF标志位
div指令后面的数是除数,被除数事先保存到ax寄存器或者dx:ax寄存器
mul和div指令对应的操作数都是无符号的,也就是不能处理负数
123456789101112131415161718192021; 8位乘法mov al, 0xf0mov ah, 0x02mul ah; 16位乘法mov ax, 0xf000mov bx, 0x0002mul bx; 16位除法mov ax, 0x0004mov bl, 0x02div bl; 32位除法mov dx, 0x0008mov ax, 0x0006mov cx, 0x0002div cx; 循环以及补0jmp $t ...
X86汇编的加减法和循环
X86汇编的加减法和循环加法:add
减法:substract
寄存器:register (8/16)
内存:memory (8/16)
立即数:immediate (8/16)
加减法CPU内部有一个标志寄存器(eflags),它的第0位就是CF位,用来保存进位和借位,当计算结果出现进位和借位时,CF会被置一
1234567891011121314151617181920; 不产生进位的加法mov ax, 0x0001mov bx, 0x0002add ax, bx; 产生进位的加法mov ax, 0xf000mov bx, 0x1000add ax, bx; 不产生进位的减法mov cx, 0x0003mov dx, 0x0002sub cx,dx; 产生进位的减法mov cx, 0x0001mov dx, 0x0002sub cx,dxxuanmai: jmp xuanmaitimes 510-($-$$) db 0db 0x55,0xaa
第一次加法时cf小写为,所以值位0,不产生进位
第二次加法CF大写,产生进位
减法同理
循环loop循环 ...
bochs调试汇编程序
bochs调试汇编程序Bochs是做系统开发常用的虚拟机,调试系统内核很方便。
Linux下调试,安装bochs-sdl
1$ nasm -f bin -o main.img main.asm
It is possible to avoid the creation of the .bochsrc file by using the following command line:
123456$ bochs \ -qf /dev/null \ 'ata0-master: type=disk, path="main.img", mode=flat, cylinders=1, heads=1, spt=1' \ 'boot: disk' \ 'display_library: sdl' \ 'megs: 128'
The qf /dev/null part is ugly, but it is the only way I’ve managed to aut ...
内存分段
内存分段内存分段在886中主要解决一个16位寄存器寻址能不不够的问题,用两个寄存器,所以就有了段地址:偏移地址的寻址方式
1M=16*64KB,16=2^4,4根线描述
1M空间最小划分段数16,最大划分段数:65535,每段16字节,因为每段最小是16字节,所以每个段的起始地址,都必须是16的倍数,这就是16字节对
16位模式也称为实模式,当我们进入32位模式的时候会有个保护模式,在保护模式下,程序不能更改其他程序的内存
汇编地址
在编译的过程中,Nasm会把编译的源文件当成一整个代码段,里面的每一条指令,都会有一个相对于代码段头部的偏移地址,这个偏移地址就叫做汇编地址。
深入了解mov指令
深入了解mov指令MOV指令MOV应用方式
去掉不可达
mov在使用的时候,源操作数和目的操作数的位宽必须一直,可以都为8位、16位等
123456789101112mov 0xb700, 0xb800mov [0x01], 0xb800mov byte [0x01], 0xb800mov word [0x01], 0xb800mov [0x01], [0x02]mov ax, [0x02]mov [0x03], axmov ds, [0x05]mov [0x04], dsmov ax, bxmov cx, dlmov cs, ds
编译报错如下:
1234567$ nasm mov.asm -o mov.binmov.asm:1: error: invalid combination of opcode and operandsmov.asm:2: error: operation size not specifiedmov.asm:3: warning: byte data exceeds bounds [-w+number-overflow]mov.asm:5: erro ...
x86汇编如何操作显卡让显示器打印字符
x86汇编如何操作显卡让显示器打印字符12mov ax, 0b800hmov ds, ax
8086CPU是一个16位的处理器,它有8个16位通用寄存器,每个寄存器都有自己的名字,而计算机经常处理单字节的数据,一个字节是8位,如果每次都用16位寄存器处理有些浪费,所以AX、BX、CX、DX这四个寄存器可以分别拆成2个8位寄存器来使用。
8086一共有20根地址线,所以寻址能力是2^20,也就是1M,8086可以找到0x00000-0xFFFFF之间的所有地址。0x00000-0x9FFFF分配给内存,一共是640KB。0xCFFFF-0xFFFFF分配给BIOS。0xAFFFF-0xBFFFF分配给了包括文字模式、图像模式在内的显示部分
显卡是支持文字模式和图形模式,其中文字模式还支持黑白和彩色两种。
图像模式包括VGA等占用0xA0000-0xAFFFF之间的64K空间,黑白模式占用0xB0000-0xB7FFF之间的32K空间。彩色文字模式占用0xB8000-0xBFFFF之间的32K空间。这些地址空间实际上以映射显卡的显存
假如显存空间有4GB,而映射的地址空间可能只有 ...
MBR分区表
MBR分区表
64字节的分区表标志,不可被破坏
qemu运行第一个X86汇编程序
qemu运行第一个X86汇编程序新建一个文件,命名为start.asm
12345678910111213141516171819202122232425262728mov ax, 0b800hmov ds, axmov byte [0x00], '2'mov byte [0x02], '0'mov byte [0x04], '2'mov byte [0x06], '2'mov byte [0x08], ','mov byte [0x0a], 'H'mov byte [0x0c], 'a'mov byte [0x0e], 'p'mov byte [0x10], 'p'mov byte [0x12], 'y'mov byte [0x14], ' 'mov byte [0x16], 'n'mov byte [0x18], 'e'mov ...



