想做个网站不知道做什么,wordpress如何上传mp3,长治做网站多少钱,寻找商机之前咱们介绍显卡上那么多的寄存器终于发挥用处了#xff0c;我们看看前文中介绍的表CRT Controller Data Registers中索引为0Eh的 Cursor Location High Register寄存器和索引为0Fh的Cursor Location Low Register寄存器#xff0c;这两个寄存器都是8位长度。分别用来存储光…之前咱们介绍显卡上那么多的寄存器终于发挥用处了我们看看前文中介绍的表CRT Controller Data Registers中索引为0Eh的 Cursor Location High Register寄存器和索引为0Fh的Cursor Location Low Register寄存器这两个寄存器都是8位长度。分别用来存储光标坐标的低8位和高8位地址。
访问CRT controller寄存器组的寄存器需要先往端口地址为0x3D4的Address Register寄存器中写入寄存器的索引再从端口地址为0x3D5的Data Register寄存器读、写数据。
接着解释之前的代码本文是连载没看过前面估计本节是蒙逼的 1 TI_GDT equ 02 RPL0 equ 03 SELECTOR_VIDEO equ (0x00033) TI_GDT RPL045 [bits 32]6 section .text7 ;------------------------ put_char -----------------------------8 ;功能描述:把栈中的1个字符写入光标所在处9 ;-------------------------------------------------------------------10 global put_char11 put_char:12 pushad ;备份32位寄存器环境13 ;需要保证gs中为正确的视频段选择子,;为保险起见,每次打印时都为gs赋值14 mov ax, SELECTOR_VIDEO ; 不能直接把立即数送入段寄存器 15 mov gs, ax1617 ;;;;;;;;; 获取当前光标位置 ;;;;;;;;;18 ;先获得高8位19 mov dx, 0x03d4 ;索引寄存器20 mov al, 0x0e ;用于提供光标位置的高8位21 out dx, al22 mov dx, 0x03d5 ;通过读写数据端口0x3d5来获得或设置光标位置23 in al, dx ;得到了光标位置的高8位24 mov ah, al2526 ;再获取低8位27 mov dx, 0x03d428 mov al, 0x0f29 out dx, al30 mov dx, 0x03d531 in al, dx3233 ;将光标存入bx34 mov bx, ax35 ;下面这行是在栈中获取待打印的字符36 mov ecx, [esp 36] ;pushad压入4×832字节,;加上主调函数4字节的返回地址,故esp36字节37 cmp cl, 0xd ;CR是0x0d,LF是0x0a38 jz .is_carriage_return39 cmp cl, 0xa40 jz .is_line_feed4142 cmp cl, 0x8 ;BS(backspace)的asc码是843 jz .is_backspace44 jmp .put_other在代码第17~31行用来获取光标值先在第19~21行设置待操作的寄存器索引我们先获取的是坐标的高8位所以要将索引0x0e写入Address Register寄存器其端口为0x03d4。
确定了要操作的寄存器是Cursor Location High Register后我们在第22~24行通过Data Register寄存器其端口是0x3d5将坐标读入到al寄存器由于al中是坐标的高8位所以第24行将其存储在ah寄存器。也许您心存疑惑既然要把坐标的高8位存到寄存器ah中为什么不把in指令中的al换成ah变成in ah, dx还多捣腾一次干吗真的抱歉对于in指令如果源操作是8位寄存器目的操作数必须是al如果源操作数是16位寄存器目的操作数必须是ax。
第26~32行用同样的方法获取到坐标的低8位至此寄存器ax中是光标完整的16位坐标值。
第35行是将光标值从ax寄存器中复制到bx这么做的原因是习惯用寄存器bx做基址寻址还记得吗在16位实模式下基址寄存器必须是bx或bp变址必须是寄存器si或di。在32位保护模式下没必要这么做了基址和变址寄存器可以是全部的32位的通用寄存器就是刚才用pushad指令压入的那8个忘了往上翻翻。以后的处理都要基于bx寄存器了在此知道bx现在已经是光标坐标值就行了它是下一个可打印字符的位置。
第36行是获取栈中压入的字符的ascii码也就是待打印的字符这是1字节的数据。栈中除了调用put_char函数的返回地址占4字节外还有最开始的pushad指令压入的8个32位的通用寄存器共32字节的数据所以待打印的字符在栈顶偏移36字节的位置。
之后的第36~44行开始判断参数是什么字符咱们这里只把回车符CRcarriage_return、换行符LFline_feed和退格键backspace当做不可见字符按照其实际控制意义来处理其它字符暂时一律认为是可见字符。回车符的ascii码是0xd换行符的ascii码是0xa我们这里的处理是不管参数是回车符还是换行符一律按我们平时所理解的回车换行符CRLF处理linux中就把换行符处理成回车换行即这两个动作的合成光标回撤到行首换到下一行。
本文是连续剧哦所以得看过之前的文章才行。下班