自制操作系统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。再键入如下命令,最后显示的是系统的中断程序执行的结果:


文/中中 浏览次数:0次   2020-04-17 17:08:17

相关阅读


评论: