标签:
第一章
内存地址空间的地址段分配
第二章
进入DOS模式
使用命令
疑问:
在书上说jmp ax指令相当于是 mov ip,ax 在实际的实践过程中发现的确是这个样子的,当IP改变,也就相当于是地址发生了变化,当前执行的指令就指向了[ax]
mov ax,bx ;1,4
sub ax,ax ;2
jmp ax ;3
要知道CPU修改几次IP就要先明白CPU什么时候会修改IP,CPU是在将指令读取到缓冲区的时候改变IP的,而不是执行一条指令而改变IP的。 所以COU修改4次IP,修改顺序在注释中列出了,最后IP值为0
第三章
关于栈:
push ax执行过程
pop ax 出栈执行过程
pop/push指令格式
push/pop 寄存器
push/pop 段寄存器
push/pop 内存单元(一个内存字单元)
关于段
一些概念
地址单元:将起始地址为N的字单元简称为N地址字单元
问题
如果将10000H~1FFFFH这段空间当做栈段,初始状态为空,此时SS=1000H,SP=?
SP = 0 不管怎么样,我们只要记住当栈为空时,栈顶是指向栈的最后一个内存字单元的下一个内存字单元的
关于寄存器
第四章
伪指令
段名 segment
段名 ends
汇编程序的结束标记
将有特定用途的段和相关的段寄存器关联起来,比如我们在使用 codesg segment . . . codesg ends 时(指定该段为代码段),需要先用assume来关联一下 eg assume cs:codesg
源程序与程序
源程序是指由指令和伪指令构成(伪指令由编译器处理)
程序是指源程序中最终由计算机执行、处理的指令或数据
程序返回
在一个程序执行完后,需要将CPU控制权限交还给CPU,不然被暂停了的程序不能被执行
mov ax,4c00H
int 21H
编译连接:
使用masm5.0 链接:http://pan.baidu.com/s/1gdg2Bwn 密码:os0e
编译
因为连接的方法是和编译的步骤一样。需要注意的也是一样,所以就不在重复。
提示:
汇编程序从写成到执行过程
编程→1.asm→编译→1.obj→连接→1.exe→加载→内存中的文件→运行
(edit) masm link command CPU
DOS系统中.EXE文件中的程序的加载过程
换个角度来看就是知道了DS就可以很好的定位到程序代码段了
注意
第五章
[bx]和内存单元
内存单元:
完整描述一个内存单元需要两种信息
eg:[0]
用[0]表示内存单元,0表示单元的偏移地址,段地址默认在ds中,单元长度(类型)可以由具体指令中的其他指令中的其他操作对象(比如寄存器)指出
[bx]:
同样表示一个内存单元,他的偏移地址在bx中,段地址默认在ds中
()符号:
用()表示一个寄存器或内存单元中的内容,()中的元素可以有3中
loop符号:
CPU在执行loop指令时,会有两个步骤
loop实例:
计算2^12
assume cs:codesg
codesg segment
mov ax,2
mov cx,11
s: add ax,ax
loop s
mov ax,4c00H
int 21H
codesg ends
end
计算ffff:0006单元中的数乘以3 记过存储在dx中 11
assume cs:codesg
codesg segment
//这里写错了,把[]与()给弄混了,()只是一个描述性符号,在汇编指令中并不存在。[]符号,是表示间接寻址,是表示的偏移地址。需要和段地址来结合使用
// mov al,[ffff6] ;因为是ffff:0006单元,一个单元只占一个字节。所以需要用一个8位寄存器来存储。所以这里用到的是al
mov ax,ffff
mov ds,ax
mov ah,0 ;清零ah
mov cx,3
mov al,[6]
mov dx,0
s add dx,al
loop
mov ax,4c00H
int 21h
codesg ends
end
DeBug和汇编编译器masm对指令的不同处理
指令 | Debug | 汇编编译器 |
mov ax,[0] | mov ax,[0] | mov ax,0 |
从表中可以看出DeBug将[idata]解释为内存单元,idata就是内存单元的偏移地址,而编译器将[idata]解释为立即数,那么如何实现在汇编编译器中将内存单元中的数据送入寄存器中?
解决方法:
1.将偏移地址送入bx寄存器中,用[bx]的方式来访问内存单元
([bx]:默认偏段地址是ds)
eg:
mov ax,2000h
moc ds,ax
mov bx,0
mov al,[bx]
2.明确给出段地址
mov al,ds:[0]
3.前两者的结合
mov ds:[bx]
解决8位寄存器不够用问题
当将12个8位数放入dx中时,因为不能直接给dx赋值,因为运算对象类型不匹配,也不能通过直接用dl累加,因为会越界所以,可以用下面的方法解决这两个问题
mov al,[bx]
mov ah,0
add dx,ax
注意
第六章 包含多个段的程序
注意:
第七章 更灵活的定位内存地址的方法
指令:
大小写转换
因为大写字母和小写字母的差别在于第6位,第6位如果为0则是大写,第六位如果为1则是小写,那么大小写转换的时候,就只需要控制好第6位就可以了。
转换成大写,即第六位为0 and 11011111
转换成小写,即第六位为1 or 00100000
[bx+idata]
上下两个是等价的
si,di
[bx+si],[bx+di]
以上两条指令等价
[bx+si/di+idata]
注意:
第八章 数据处理的两个基本问题
reg:ax,bx,cx,dx,ah,al,bh,bl,ch,cl,dh,dl,sp,bp,si,di
sreg:ds,ss,cs,es
内存单元寻址
汇编指令 | 指令执行前数据的位置 |
mov bx,[0] | 内存,ds:0单元中 |
mov bx,ax | CPU内部,ax寄存器 |
mov bx,1 | CPU内部,指令缓冲器 |
指令执行前,它将要处理的数据所在位置
div指令
第九章 转移指令的原理
8086CPU的转移指令分类
offset指令:取得标号的偏移地址
jmp指令:无条件跳转指令,可以只修改ip,也可以同时修改ip和cs,在使用jmp的时候,需要给出下面两种信息
jmp short 标号(转到标号处执行指令) ip修改范围 -128~127 段内短转移
jmp near ptr 标号 -32768~32767 段内近转移
jmp far ptr 标号 段间转移,又称为远转移
jmp word ptr 内存地址单元
jmp dword ptr 内存单元地址 cs = (内存单元地址+2),ip=(内存单元地址)
jcxz指令:条件转移指令,所有的条件转移指令都是短转移
条件,如果cx=0,则跳转到标号处执行
loop指令
循环指令,所有的循环指令都为短指 cx=cx-1
实验9
assume cs:code,ds:data
data segment
db ‘Welcome to asm! ‘
data ends
code segment
start: mov ax,data
mov ds,ax
mov ax,0B800h
mov es,ax
mov bx,0
mov si,0
s: mov cx,16
mov al,[bx]
mov es:[si+720h],al //注意这里,写720h是因为显示的原因,前面第0行和第1行会被后面的覆盖掉,所以如果从0开始的,我们会看不到效果
mov al,01000010b
mov es:[si+721h],al
inc bx
add si,2
loop s
mov ax,4c00h
int 21h
code ends
end start
win7程序能够运行,但是不能显示效果,但是在xp下能够完美的显示
第十章 call和ret指令
ret:用栈中的数据,修改ip内容,从而实现近转移
retf:硬栈中数据,修改cs和ip的内容,从而实现远转移
call
call指令不能实现短转移,除此之外,call指令实现转移的方法和jmp指令的原理是相同的
call 标号
push ip
jmp near ptr 标号
call far ptr 标号
push cs
push ip
jmp far ptr 标号
转移地址在寄存器中的call指令
push ip
jmp 16位reg
cs:reg
换一个地址在内存中的call指令
push ip
jmp word ptr 内存单元地址
mul指令
第十一章 标识寄存器
15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0
OF | DF | IF | TF | SF | ZF | AF | PF | CF |
ZF标志
零标志位,记录相关指令执行后,结果是否为0,如果为0,ZF=1,如果不为0,ZF=0
PF标志
奇偶标志位,记录相关指令执行后,其结果的所有bit中1个个数是否为偶数位,如果为偶数,PF=1
SF标志
符号标志位,记录相关指令执行后,其结果是否为负,如果为负,SF=19(计算机中通常用补码来表示有符号数据)
我们在将数据当做有符号的数据来运算的时候,可以通过它来得知的值结果的正负
如果我们将数据当做无符号的数据来运算的时候,SF的值就没有意义了,虽然相关指令影响了它的值
CF标志
进位标志位,在进行无符号数运算的时候,他记录了运算结果的最高有效位向更高位的进位值,或从更高的借位值,相关执行执行后,进位CF=1,不进位CF=0
OF标志
溢出标志位,在有符号运算中,如果超出了寄存器所能存放的范围。
adc指令:带位加法指令
adc 操作对象1,操作对象2
操作对象1=操作对象1+操作对象2+CF
sbb指令带借位减法指令
sbb 操作对象1,操作对象2
操作对象1=操作对象1-操作对象2-CF
cmp指令:
比较指令,功能相当于减法指令,但是不保存结果,但是会影响标志寄存器
指令 | 含义 | 检测的相关标志位 |
je | 等于则转移 | ZF=1 |
jne | 不等于则转移 | ZF=0 |
jb | 低于则转移 | CF=1 |
jnb | 不低于则转移 | CF=0 |
ja | 高于则转移 | CF=0或ZF=0 |
jna | 不高于则转移 | CF=1或ZF=1 |
DF标志和串传送指令
方向标志位,控制每次操作后si,di的自增自减
DF=0 每次操作后,si,di自减
DF=1 每次操作后,si,di自增
DF指令配合串操作指令使用的
eg
movsb,将ds:si指向的内存单元中的字节送入es:di中,根据DF位,决定si,di是自增还是自减
pushf 和popf
pushf的作用是将标志级传奇的值压栈,而popf的作用是从栈中弹出数据送入标志寄存器
标签:
原文地址:http://www.cnblogs.com/kangxiaopao/p/4898740.html