自制操作系统07--汇编语言(王爽)学习笔记1
汇编语言(王爽)学习笔记一
前文谈到,使用《30天自制操作系统》作者的工具,可以非常方便, 但不利于我们学习到底层知识。也无法用通用的masm,nasm等修改源码,实现自己的功能。为此,我买了王爽老师的《汇编语言》第三版,来学习和理解底层技术。收获不小,书有300多页,但本文记录的内容不全面也不系统,但很关键,为以后的学习留下笔记。
windows xp,DOS环境,进入项目目录.
masm相关工具的下载链接:https://github.com/jie12366/MASM,下载后解压就能用。
环境变量path应配置了masm的目录。
1.生成obj文件(路径请自行替换)
masm c:\cz\masm\wangs\7_9.asm
2.生成exe文件
link 7_9.obj
3.debug 7_9.exe
一些8086下的关键知识点:
ds不能放立即数,但可放寄存器数。
cx是计数器,loop会自动减小cx里的值
bx是常用地址寄存器,意思是可以mov dx,[bx],而不能dx,[ax]
ax常用成临时变量,比如:mov ax,123h ;第二行 mov ds,ax
只要在[...]中使用寄存器bp,而指令中没有显性的给出段地址,段地址就默认在ss中。
进入debug环境后,先用r命令查看当前寄存器值:
先用r命令可以查到数据段(DS)值为0b9d,那么根据书中第三章内容可知,程序的开始地址为DS:100,前100(256字节)是PSP内容。然后用d b9d:100命令查看地址与汇编代码的关系,如下图:
dw是define word的缩写,就是定义字,一个字为两个字节。但为什么我代码里定义了4个变量,在第二行却显示为16个字节呢?原来dw后面都是以16字节为单位的,小于等于8个数(字),就是16字节。大于8,就要加上整数倍个16字节。可以试验出结果。
然后我们可以看到代码段寄存器(CS:IP)为 bb3:0,那么我们对比一下debug出的代码与真实代码,键入u bb3:0,得到下面的结果:
以下代码是第七章后面的习题:
编程,将datasg段中每个单词的前4个字个母改为大写字母。
assume cs:codesg,ss:stacksg,ds:datasg stacksg segment dw 0,0,0,0,0,0,0,0 stacksg ends datasg segment db '1. display ' db '2. brows ' db '3. replace ' db '4. modify ' datasg ends codesg segment start: mov ax,datasg mov ds,ax mov ax,stacksg mov ss,ax mov sp,16 mov bx,0;datasg部分的下标 mov cx,4 outter: push cx ;把循环变量cx存到栈里 mov cx,4 ;内层循环变量 mov si,0 inner: mov al,[bx+3+si] and al,11011111B ;ASCII码的第5个位置,将al中的字母变为大写 mov [bx+3+si],al inc si loop inner add bx,16 pop cx loop outter codesg ends end start
第九章习题:
在屏幕中间分别显示绿色、绿底红色、白底蓝色的字符串'welcome to masm!'。
assume cs:codesg datasg segment db 'welcome to masm' datasg ends paramsg segment db 0CAh,02h; ;样式参数 paramsg ends codesg segment start: mov bx,0140h ;第3行 mov cx,15 ;字符串总长为15 mov di,0 ;字符下标 s: ;mov dh,2 ;设置样式 mov si,paramsg mov ds,si mov si,0 mov dh,[si] ;设置样式 mov ax,datasg mov ds,ax mov dl,[di] mov ax,0b800h ;屏幕内存地址 mov ds,ax mov word ptr [bx],dx; add bx,2; inc di; loop s mov ax,4c00h int 21h codesg ends end start
第十章call的使用对寄存器的影响:
下面代码执行后,ax中的数值为多少
assume cs:codesg codesg segment start: mov ax,0 call s ;sp初始化时为0。 ;call s 执行这样的操作 ;(sp)=(sp)-2 sp成负数了,用补码表示,-2的补码是FFFE ;((SS)*16+(sp))=(IP) ;这里的ip是下一句的地址ss:6 ;(IP)=(IP)+16位位移 inc ax s: pop ax codesg ends end start
答案是6
中断:学习除以0,发生中断的示例代码,先进入debug。再键入如下命令,最后显示的是系统的中断程序执行的结果:
相关阅读
评论:
↓ 广告开始-头部带绿为生活 ↓
↑ 广告结束-尾部支持多点击 ↑