要完整的描述一个内存单元,需要两种信息:a内存单元的地址;b内存单元的长度(类型)。
用 [0] 表示一个内存单元时, 0 表示单元的偏移地址,段地址在 DS 寄存器中,单元的长度由具体指令中其他的操作对象来决定,比如 mov ax,[0] ,这时 [0] 表示一个字单元,占两个字节, mov al,[0],这时 [0] 表示一个字节单元,占一个字节。同理[bx]也是表示一个内存单元,只是它的偏移地址保存在 bx 中。
我们用 (ax) 表示 ax 中的内容,(al) 表示 al 中的内容。
对于 push ax 的功能,可以这样描述:(sp)=(sp)-2;((ss)*16+(sp)) = (ax)
对于 pop ax 的功能,可以这样描述:((ss)*16+(sp)=(ax)) ;(sp)=(sp)+2
loop 指令的使用:
loop 指令的格式是:loop 标号,CPU 执行 loop 指令的时候,要进行两步操作,①(cx)=(cx)-1;②判断 cx 中的值,不为零则转换至标号处执行程序,如果为零则向下执行;
例子:计算 2^12
assume cs:code
code segment
mov ax,2
mov cx,11
s:add ax,ax
loop s
mov ax,4c00h
int 21h
code ends
end
s 是一个标号,代表一个地址,这个地址处有一条指令:add ax,ax
执行 loop s 的时候,要进行两步操作:
① (cx)=(cx)-1
② 判断 cx 中的值如果为 0 则执行循环后的第一条指令,否则执行 s 所标识的地址
在汇编源程序中,数据不能以字母开头,比如 mov ax,0ffffh 不能写成 mov ax,ffffh
执行 loop 命令时,会先将 cx 减 1,如果 cx 不为 0 则 ,将 IP 设置为 标号 S 所在的地址,及循环体第一条命令所在的地址,如果为 0 了,则 本条 loop 指令不会生效,IP 会指向下一条命令所在的地址,在 debug 中最后一条命令 int 21h 要用p 命令来执行。
g 命令的使用:一次执行到 循环体标识,s 所在的位置,格式 g 0012(循环体第一条命令的位置,即 loop 指令后的地址值)
p 命令的使用:在循环体中时,想要一次将循环执行完,可以使用 p 命令,即运行循环,直到 cx=0 为止,当然也可以用g 命令来实现。
debug 和 汇编编译器的对某些命令的不同解释:mov al,[0] 在debug 只能中解析为 将 DS:0 中的数据覆盖到 al 中,而汇编编译器解释其为, 将 mov ax,0 。在汇编源程序中 可以通过显式的指定 段寄存器来实现在 debug中那样的效果,即 mov ax,ds:[0],或者 mov bx,0 mov ax,[bx] 或者 mov bx,0 mov ax,ds:[bx] 。
段前缀:出现在访问内存单元的指令中,用于显式的指明内存单元的段地址的“ds” “cs” “ss” “es” 在汇编语言中称为段前缀。
一段安全的空间: 0:200~0:2ff
段前缀的使用:将内存 ffff:0 ~ ffff:b单元中的数据复制到 0:200 ~ 020b 中
通过段前缀的实现