2020-11-29 汇编语言1-7章 基础篇

汇编语言调试几个常用指令

d:查看内存中的值
e:
u:翻译成汇编指令
t:执行
a:以汇编指令的格式再内存中写入一条机器指令


第4章 第一个程序(这章挺重要的)
4.2源程序
assume cs:codesg
codesg segment
mov ax 0123H
mov bx,0456H
add ax,bx
add ax,ax

mov ax,4c00H
int 21H
codesg ends
end

解释:1、汇编语言源程序包括汇编指令和伪指令
2、xxx segment ..........xxx ends 是成对的伪指令,定义了一个段
3、end 汇编程序结束符
4、assmue 将这个段和对应的段寄存器联系起来
5、程序的返回代码


4.3 编辑源程序edit命令
4.4 编译
masm.exe 1.asm
4.5 链接
link.exe 1.obj

4.9 debug程序执行跟踪
1、为了观察程序的执行过程,可以使用Debug.Debug可以将程序加载到内存,设置CS:IP指向程序的入口;
2、debug程序时:CS:IP指向程序的入口(也就是第一条指令的地方)而不是源程序的入口(重要)
3、可执行文件载入内存后,cx寄存器存放了程序的长度,即机器码共有15个字节(重要)
4、加载后,ds中存放着程序所在内存区的段地址,偏移地址为0;ds+10就是整个源程序的地址(重要)
5、ds和cs相差0010(256字节),创建一个程序段前缀256字节PSP

2020-11-29 汇编语言1-7章 基础篇

2020-11-29 汇编语言1-7章 基础篇

 

第五章 [bx]和[loop]
5.1 bx中存放的数据作为偏移地址EA,段地址SA默认再ds中;所以在使用bx时应该先初始化ds的值
mov ax,2000h
moc ds,ax
mov ax,[bx]
5.2 loop指令
1、执行loop s时,1.(cx)=(cx)-1; 2.判断cx值,不为0则跳到s标识处
2、使用框架
        mov cx,循环次数
       s:
        循环执行的代码
        loop s

编程用加法算123*236
assume cs:code
code segment
        mov ax,0
        mov cx,236
       s:add ax,123
        loop s
        
        mov ax,4c00h
        int 21h
code ends
end

5.3 Debug中跟踪loop
计算ffff:0006单元中的数乘3,结果放在dx中
(1)单元只有8位,结果放在16位寄存器中,不会越界
(2) mov al,[6]
         mov ah,0
       s:add dx,ax 循环
5-3程序实现
assume cd:code
code segment
        mov ax,0ffffh
        mov ds,ax
        mov bx,6
        
        mov al,[bx]
        mov ah,0
        mov dx,0
        mov cx,3
    s:add dx,ax
        loop s

        mov ax 4c00h
        int 21h
code ends
end    

5.5 loop和[bx]的联合使用
计算ffff:0~ffff:b单元中的数据的和,结果放在dx中
(1)结果会不会越界?8位累加放在16位寄存器不会越界
(2)直接累加不行,8位不能直接加到16位上,利用中间寄存器ax,ah=0;
5-5实现
assume cs:code
code segment
        mov ax,0ffffh
        mov ds,ax
        
        mov dx,0

        mov al,ds:[0]
        mov ah, 0
        add dx,ax

        mov al,ds:[1]
        mov ah, 0
        add dx,ax
        
        ......
        mov al,ds:[0bh]
        mov ah, 0
        add dx,ax    

5-6改进后程序
        mov cx,12
    s:mov al,[bx]
        mov ah,0
        mov dx,ax
        inc bx
        loop s

        mov ax,4c00h
        int 21h
code ends
end


5-8将内存ffff:0单元数据复制到0:200~0:20b
(1)他们在不同的段,该怎么复制?每次循环重新设置ds
assume cs:code
code segment
        mov bx,0
        mov cx,12
        
    s:mov ax,0ffffh
        mov ds,ax
        mov dl,[bx]

        mov ax,0020
        mov ds,ax
        mov [bx],dl

        inc bx
        loop s

        mov ax,4c00h
        int 21h
code ends
end 
5-9可以使用两个段寄存器来存放两个段地址ds=ffffh,es=0020h
assume cs:code
code segment
        mov ax,0ffffh
        mov ds,ax

        mov ax,0020h
        mov es,ax

        mov bx,0
        mov cx,12
    s:mov dl,[bx]
        mov es:[bx],dl
        inc bx
        loop s

        mov ax,4c00h
        int 21h
code ends
end

每条指令占用的字节数

  2020-11-29 汇编语言1-7章 基础篇  

 
第六章 包含多个段的程序
6.1 数据段
6-2 计算8个数据的和,保存在ax中
assume cs:code
code segment
        dw 0123h,0333h,0678h,0324h,0343h,0333h.0acbh,0999h   //定义字段,cs指向的16字节保存这数据
        
        mov bx,0
        mov ax,0

        mov cx,8
        s:add ax,cs:[bx]        //如果不指定cs,系统会去读ds:[bx]中的值
        add bx,2
        loop s

        mov ax,2c00h
        int 21h
code ends
end

我们可以直接指定cs:ip到真正要执行的代码处:
assume cs:code
code segment
        dw 0123h,0333h,0678h,0324h,0343h,0333h.0acbh,0999h   //定义字段,cs指向的16字节保存这数据
        
start:mov bx,0   //这个start的作用就是把ip直接指向这里,但是前面的dw16字节依然在cs段内,用cs:[bx]依然可以引用
        mov ax,0

        mov cx,8
        s:add ax,cs:[bx]        //如果不指定cs,系统会去读ds:[bx]中的值
        add bx,2
        loop s

        mov ax,2c00h
        int 21h
code ends
end start 告诉程序入口在哪里

6.2 在代码段中使用栈(同理)
6-3将数据逆序存放 
assume cs:code
code segment
        dw 0123h,0333h,0678h,0324h,0343h,0333h.0acbh,0999h
        dw 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0     //16个字节,把它当成栈使用

    start:mov ax,cs
        mov ss,ax
        mov sp,30h   //把栈顶位置确定下来,栈为空
    
        mov bx,0
        mov cx,8
        s:push cs:[bx]
        add bx,2
        loop s
        //入栈
        s0:pop cs:[bx]
        add bx,2
        loop s0

        mov ax,4c00h
        int 21h
code ends
end    

6.3 将数据、代码、栈放入不同的段
6-4
assume cs:code,        ds:data,        ss:stack         //将寄存器和段联系起来      
data segment
        dw 0123h,0333h,0678h,0324h,0343h,0333h.0acbh,0999h
data ends

stack segment
        dw 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
stack ends

code segment
    start:mov ax,stack            stack在这里等价16为地址例如1CD4
        mov ss,ax               //设置栈段的位置ss:sp
        mov sp,20h

        mov ax,data
        mov ds,ax                //设置数据段的位置ds,bx

        mov bx,0
        mov cx,8
s:push [bx]
        add bx,2                //入栈        
        loop s

        mov bx,0
        mov cx,8
s0:pop [bx]                //出栈
        add bx,2
        loop s0

        mov ax,4c00h
        int 21h
code ends
end

注意:执行到ds赋值的时候就可以通过d ds:0来查看内存中的值了

第七章 更加灵活的定位内存地址的方法

2020-11-29 汇编语言1-7章 基础篇

7.1 and和or指令
mov al,01100011B
and al,00111011B

mov al,01100011B
or  al,00111011B

7.3以字符形式给出的数据

7-1
assume cs:code, ds:data
data:segment
    db 'unIX'
    db 'foRX'
data ends
code:segment
    start:move al,'a'
    mov bl,'b'
code ends
end start
这个简单的汇编程序中;debug用r查看寄存器,ds指向整个源程序开始的地方1cc3,加上256字节(psp)后就是程序的起始处1cd3:0;
然后再加上‘unIX’‘foRX’占用一个段(16字节也就是8个字)0B3E

2020-11-29 汇编语言1-7章 基础篇

2020-11-29 汇编语言1-7章 基础篇

7.4大小写转换的问题
思路:某个字母可以用8位表示(128);例如a:97 A:65;相差32;只需要将第5位置1就位小写00100000

and al,11011111 把第五位置0
程序例题大小写问题
assume cs:codesg, ds:datasg
datasg segment
db 'BaSiC'
db 'iNdPrMAtiN'
datasg ends
codesg segment
start:mov ax,datasg
mov ds,ax
mov bx,0
mov cx,5

s:mov al,[bx]
and al,11011111B      小写变大写,本来是大写就不用变
mov [bx],al        改了之后放回去
inc bx
loop s

mov bx,5
mov cx.10

s0:mov al,[bx]
or al,00100000B
mov al,[bx]
inc bx
loop s0

mov ax 4c00h
int 21h
codesg ends
end start

接下来几节主要就是讲如何定位内存单元的问题;新增si和di两个指令
7.5 [bx+idata]我们把idata具体化位200
意思就是表示一个内存单元,偏移地址(bx)+200;先看看bx里面的值再加上200
例如:mov ax,[bx+200]
等价于:mov 200[bx] == mov ax,bx.200
7.7 si和di寄存器
其实和bx寄存器相似,只是si和di不能够分成两个8位寄存器来使用
7.8 [bx+data]和[bx+di]
7.9 [bx+si+data]和[bx+di+idata]

上一篇:《汇编语言》——王爽实验4


下一篇:实验2 汇编源程序编写与汇编、调试