本系列文章参考汇编语言第四版和汇编语言程序设计 贺利坚主讲整理而成
上面的写法需要用offset来指明代码段中数据的地址
a[si]---->[si+a]
mov al,b报错是因为b操作的内存单元是字大小,而al是字节大小,不符合
上面都是将数据放在了代码段中,但是一般都是各段分隔开来存放。
如果将数据标号当做数据来定义,那么对应保存的是这个数据标号指向的内存地址
a db 123
b dw 0
#c标号指向内存单元,保存了两个字数据,一个是a标号指向的内存偏移地址,另一个是b标号指向的内存偏移地址
#此时c可以看做是指针的指针
c dw a,b
a db 123
c dw 0
#c表示指向内存单元,保存了两个双字数据,对于每个双字数据而言,前一个保存了对应偏移地址,后一个保存了对应段地址
c dd a,b
当我们将数据标号作为数据定义的时候,是不是特别类似C语言中的指针的指针
00101011 是作为低字节存放在al中的,其中前后四位各组成0-15中一个数字,然后去字符表中定位对应的位置的字符
这里重点关注的不在是各个功能的具体实现了,而是主程序中通过查表得到每个子程序开始的地址,这个操作是如何完成的
查表可以提高速度,并且可以使程序架构非常清晰易懂,也便于程序扩充。查表的思想与策略模式类似,都是用来解决一堆IF...ELSE判断的
并且因为每个中断程序占据四个字节,因此IP与N是有规律可循的,IP=N4,CS=N4+2
当发生中断时,先查表得到中断程序的地址,然后设置CS和IP的值即可去执行中断程序
当发生除法错误时,触发0号中断,此时会去查表得到0号中断程序的地址,然后设置CS和IP指向中断程序地址,然后执行中断程序
执行中断程序前需要先保护现场,这点很重要,主要是保存标志寄存器的状态和当前程序的地址
安装程序就是把程序代码送入到先前指定存放程序的内存空间中去,然后更改中断向量表0号表项存放的0号中断程序的地址即可。
程序占用的总共字节数,可以通过两个地址标号表示地址直接差值算出来
显示字符,就是将对应字符写出到显示缓冲区即可,然后设置中断向量表就是将do0中断程序的入口地址,写入到中断向量表的0号表项中
因为do0中断程序中mov ax,4c00h int 21h会直接结束程序运行,返回DOS系统,因此并不会在中断程序执行结束后,返回原有程序继续执行。
如果在执行向ss寄存器传送数据的指令时,发生了中断,那么CPU会将相关中断寄存器值设置为0,不允许中断产生,这样下一条指令会继续执行,执行完下一条指令后,再进入中断
因此右边的写法是错误的,因为这样写的话,mov ss,ax和mov ax,0会一起连续执行,而mov sp,10指令会单步执行
在执行int n中断之前,会把当前CS和IP寄存器状态入栈,还有标志寄存器状态入栈,然后中断例程执行结束后,再将相关状态出栈,进行现场还原。
如果中断程序中使用到了相关寄存器,也需要在使用前保存对应寄存器状态,程序结束后恢复
CPU通过这些端口控制各种芯片的行为,这些端口实质就是寄存器,但是是与对应芯片相关的寄存器,不是cpu内部从寄存器,这些芯片通过读取这些寄存器的值,知道自己应该干什么
in al, 20h
out 21h, al
控制键和切换键由键盘状态字节负责存储,该字节每一位都代表一个按键的状态
空循环的设计给出一个思路:dx和ax都赋值一个最大值,然后先把ax寄存器的值减到0结束,结束后再把dx的值也减到0
在轮询显示a–z的过程中,按下任何键,如果触发了中断,首先会去调用其原本的中断例程,原本的中断例程执行结束后,如果按下的是ESC键还会去额外改变当前显示字体的颜色,如果是其他键,就没有额外的功能了
上面是输入完ABCDE后的,键盘输入缓冲区的状态,下面输入SHIFT_A
此时我们再按下一个A
Shift标志为还原
用int 16h读取出 用int 9h存入缓 冲区的数据
键盘缓冲区的实现
依次从键盘缓冲区读取出一个字,放入数据缓冲寄存器,然后再放入AX中,AH存放扫描码,AL存放ASCII
当一个程序中存在若干子功能的时候,一般不采用挨个判断方式,而采用查表法来决定当前应该调用哪一个子功能
程序可以直接访问外设,是通过端口的形式进行访问的
让计算机唱歌,需要与8253和8255芯片打交道,而CPU想要控制这两个芯片,需要通过对应两个芯片提供的端口进行操控
因为进行了统一编址,所以我们可以很容易定位到这两个端口的地址都是什么,然后通过in和out指令写入数据操作它,获取从对应的端口读取出我们需要的数据。
版权说明 : 本文为转载文章, 版权归原作者所有 版权申明
原文链接 : https://cjdhy.blog.csdn.net/article/details/125374505
内容来源于网络,如有侵权,请联系作者删除!