x86汇编语言学习

操控显存输出字符串

  • 使用不中断的方式打印字符串

  • 在8086的内存地址结构中,B8000H~BFFFFH这部分的内存区域为显存区域,一旦向这个地址空间写入数据,cpu会从0号偏移地址开始读取数据然后显示输出, (每写入一次数据就从0开始读取一次)

  • 在这块区域中,每个字符固定占用两个字节的空间,也就是ds:[0]ds:[1]存放一个字符的信息,前者存放字符具体的内容,后者存放字符对应的颜色

  • 字符颜色的设置规则:

    0 0 0 0 0 0 0 0 ;用8个二进制位表示字符属性

    1. 从高位往低位数,第1个二进制位表示是否显示闪烁痕迹,设为1即保留字符闪烁痕迹
    2. 第234位表示字符背景颜色,分别代表R(red)G(green)B(blue)
    3. 第5个二进制位表示字符是否高亮。设为1即字符高亮显示
    4. 第678个二进制位表示字符本身的颜色,分别表示RGB
  • data segment
        
        str db "hello world"   
        
        endstr db ''
        
    data ends
    
    code segment
        start:
        
            mov ax, data
            mov ds, ax
            
            mov ax, 0B800H
            mov es, ax 
            
            mov cx, offset endstr - str ;字符串的长度  
            
            mov bx, 0 
            mov si, 0
        print:
            mov al, ds:[si]     ;【】内使用bx或di或si
            mov es:[bx], al     ;ax是16位的,为避免颜色改变,使用al
            add bx, 2 
            inc si ;si = si+1
            
            loop print
            
    code ends
    
    end start
    
  • 由于CPU会从0号偏移地址开始读取数据,然后显示输出,因此假如直接在6号偏移地址写入字符数据,那么前三个数据会以占位形式存在

start:
	mov ax, 0B800H
	mov ds, ax
	
	mov dl, 'a'
	mov ds:[0], dl
	
	mov dl, 000000111B
	mov ds:[6], dl  ;输出结果为"   a"
end start
  • 借助字符不断刷新显示的特性,可以让字符动画显示
;让字符从左往右移动

code segment
    start:
    
        mov ax, 0B800H
        mov es, ax 
        
        mov cx,100  ;移动100次
        
        mov bx, 2 
        
    print:
        mov al, ' '    
        mov es:[bx-2], al    
        mov al,'a' 
        mov es:[bx], al
        add bx,2
        
        loop print

code ends

end start
  • 屏幕默认显示80x25个字符,全屏显示106x38个字符,那么可以根据这个特性,让字符上下移动
 ;从上往下移动                                                            
code segment
    start:
    
        mov ax, 0B800H
        mov es, ax 
       
        mov bx, 0
        mov cx, 25
        
    print:
        mov al, 'a'    
        mov es:[bx], al   
        
        mov dl, ' '
        mov es:[bx-160], dl    ;把前面的a都清除
    
        add bx,160   ;80个字符,每个字符占用2个字符空间,
        
        loop print
        
        
        
        
code ends

end start
  ;从下往上移动                                                           
code segment
    start:
    
        mov ax, 0B800H
        mov es, ax 
       
        mov bx, 160*25
        mov cx, 25
        
    print:
        mov al, 'a'    
        mov es:[bx], al   
        
        mov dl, ' '
        mov es:[bx+160], dl    
    
        sub bx,160   ;80个字符,每个字符占用2个字符空间,
        
        loop print
   
        
code ends

end start

使用键盘输入操纵字符移动

  • 使用16号中断码
;使用键盘上的wsad控制字符上下左右移动
code segment
    start: 
        mov ax, 0B800H
        mov es, ax
        
        mov bx, 0
        
        scan:
            mov ah, 00H  
            int 16H     ;使用16号中断码
            
            cmp al, 61H ;cmp的作用是判断al中数据的值与61H是否相等
            jne scan2   ;jne意即jump not equal, 如果二者不相等,则跳转到手残2,否则往下执行
            call left
            jmp scan    ;jmp 跳转到指令所在位置
        
        scan2:
            cmp al, 64H
            jne scan3
            call right
            jmp scan
        
        scan3:
            cmp al, 77H
            jne scan4
            call top
            jmp scan
            
        scan4:
            cmp al, 73H
            jne scan
            call down
            jmp scan
            
            
        right:
            mov es:[bx], ' '
            mov dl, 'a'
            mov es:[bx+2], dl
            add bx, 2
            ret ;ret的作用是回到call的下一条指令
        
        left:
            mov es:[bx], ' '
            mov dl, 'a'
            mov es:[bx-2], dl
            sub bx, 2
            ret
        
        top:
            mov es:[bx], ' '
            mov dl, 'a'
            mov es:[bx-160], dl
            sub bx, 160
            ret
            
        down:
            mov es:[bx], ' '
            mov dl, 'a'
            mov es:[bx+160], dl
            add bx, 160  
            ret
    
    
code ends
end start
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值