x86汇编学习历程4----在屏幕上显示数字

先贴代码

start:  ;//标号(冒号可去)
	mov ax, 65535
	xor dx, dx      ;等价于mov dx, 0(寄存器间操作更快)
	mov bx, 10
	div bx          ;//ax/bx==65535/10 ax=商(65535), dx=余数(5)

	add dl, 0x30    ;//(0x30是16进制的"0"字符)
	;//将数字转换为对应的数字字符存到dl中
	;//(此处dl是dx的低八位)

	mov cx, 0       ;//将段地址0传送到数据段ds
	mov ds, cx      ;//不能直接传,要借助寄存器传

	mov [0x7c00+buffer], dl        
	;//将dl中的字符编码传送到ds段内的偏移地址处(也就是buffer第一个0)
	;//dl为8位长度,以字节单位进行

	xor dx, dx      ;//dx中内容已保存,清零dx
	div bx
	add dl, 0x30
	mov [0x7c00+buffer+1], dl
;//将dl中的字符编码传送到ds段内的偏移地址加一处(也就是buffer第二个0)
	xor dx, dx
	div bx
	add dl, 0x30
	mov [0x7c00+buffer+2], dl
;//将dl中的字符编码传送到ds段内的偏移地址加二处(也就是buffer第三个0)
	xor dx, dx
	div bx
	add dl, 0x30
	mov [0x7c00+buffer+3], dl
;//将dl中的字符编码传送到ds段内的偏移地址加三处(也就是buffer第四个0)
	xor dx, dx
	div bx
	add dl, 0x30
	mov [0x7c00+buffer+4], dl
;//将dl中的字符编码传送到ds段内的偏移地址加四处(也就是buffer第五个0)

buffer:   ;//标号(冒号可去)
	db 0,0,0,0,0
	
current:  ;//标号(冒号可去)
	times 510-(current-start) db 0
	db 0x55, 0xaa
除操作div
如果在指令中指定的是8位寄存器或8位操作数的内存地址,
则意味着被除数在寄存器AX中,相除后商在寄存器AL里余数在寄存器AH里
列:
 ___________
|___________| 2002
div bh ;bh是位寄存器 
div byte [0x2002] ;byte一个字节
如果在指令中指定的是16位寄存器或16位操作数的内存地址,
则意味着被除数是32位的,相除后商在寄存器AX里余数在寄存器DX里
列:
 ___________
|___________|
|___________| 2002
div bx ;被除数是32位的
div word [0x2002] ;word一个字(两个字节)
如果在指令中指定的是32位寄存器或32位操作数的内存地址,
则意味着被除数是64位的,相除后商在寄存器EAX里余数在寄存器EDX里
列:
 ___________
|___________|
|___________|
|___________| 
|___________| 2002
div ebx ;(EAX与EDX组合成一个64位的被除数除以ebx的内容)
div dword [0x2002] ;dword两个字(四个字节)
如果在指令中指定的是64位寄存器或64位操作数的内存地址,
则意味着被除数是128位的,相除后商在寄存器RAX里余数在寄存器RDX里
列:
 ___________
|___________|
|___________|
|___________| 
|___________| 
|___________|
|___________|
|___________| 
|___________| 2002
div rbx 
div qword [0x2002] ;dword四个字(八个字节)
异或操作xor (00=0 01=1 10=1 11=0)
xor r/m r/m/imm
;r代表寄存器,m代表内存地址,imm代表立即数(两个数据长度必须相同)
列:
xor ax, 3 ;把3当作16位
xor word [0x2002], 67 ;把67当作16位
xor si, [0x2002] ;从[0x2002]中读取一个16位再进行异或
加操作add
add r/m r/m/imm

传送到显存

	mov al, [0x7c00+buffer+4]
	
	mov cx, 0xb800  ;//将ds段寄存器改为显存的地址
	mov ds, cx

	mov [0x00], al  ;//[0x00]相对0xb800偏移地址
	mov byte [0x01], 0x2f
-------------------------------------------------------------
	mov cx, 0
	mov ds, cx  ;//将ds段地址改为原来的以便取数字字符

	mov al, [0x7c00+buffer+3]

	mov cx, 0xb800
	mov ds, cx

	mov [0x02], al
	mov byte [0x03], 0x2f
	...
	... ;//重复取完

以上代码较为麻烦
所以我们借用附加寄存器es完成操作,代码如下:

	mov cx, 0xb800
	mov es, cx

	mov al, [0x7c00+buffer+4] 
	mov [es:0x00], al  ;//"es:"是段超越前缀
	mov byte [es:0x01], 0x2f  ;//0x2f是颜色属性指令

	mov al, [0x7c00+buffer+3] 
	mov [es:0x02], al  ;//"es:"是段超越前缀
	mov byte [es:0x03], 0x2f  ;//0x2f是颜色属性指令

	mov al, [0x7c00+buffer+2] 
	mov [es:0x04], al  ;"es:"是段超越前缀
	mov byte [es:0x05], 0x2f  ;0x2f是颜色属性指令

	mov al, [0x7c00+buffer+1] 
	mov [es:0x06], al  ;"es:"是段超越前缀
	mov byte [es:0x07], 0x2f  ;0x2f是颜色属性指令

	mov al, [0x7c00+buffer] 
	mov [es:0x08], al  ;"es:"是段超越前缀
	mov byte [es:0x09], 0x2f  ;0x2f是颜色属性指令

again:
	jump again ;//一直循环
加上段超越前缀就是以es作为段地址,没加就是以ds为准

编译后 将bin文件写入虚拟硬盘
打开bochs调试如图所示

在这里插入图片描述
至此结束

  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值