5.1,2
mov ax,[bx]表示将偏移地址和段地址分别在BX,DS的内存单元的内容放入ax中。
inc bx含义为bx内容加一。
loop指令格式:
mov cx,11 (cx存储循环次数,每次循环后-1,为0时转到loop s后继续执行指令)
s: add ax,ax (循环执行的程序段)
loop s 【效果相当于(ax)的12次方。】
5.3 在debug中跟踪用loop指令实现的循环程序:P103
重点:图5.8
可用g命令直接跟踪循环。
g 0012 意思为执行代码段到当前代码段的0012h处(段地址在cs中)
当希望将循环一次执行完时,用P命令完成,具体:遇到loop指令时,用p命令Debug自动重复执行循环的指令直到(cx)=0.
5.4Debug和汇编编译器masm对指令的不同处理
mov al,[0] debug认为【0】为内存单元的偏移地址;masm解释为0。
解决:
mov ax,2000h
mov ds,ax
mov bx,0 将内存单元地址赋给bx
mov al,[bx]
或在内存地址单元的偏移地址前加上段地址所在寄存器如:
mov ax,2000h
mov ds,ax
mov al,ds:0 --------(ds就是5.6中的段前缀)
5.5 loop,bx联合运用
mov ax,0ffffh
mov ds,ax
mov bx,0 ds:bx指向ffff:0
mov dx,0 (累加寄存器)
mov cx,12
s: mov al,[bx]
mov ah,0
add dx,ax
inc bx (bx)每次循环加一
loop s
5.6参上
5.7
8086模式中,随意向一段内存地址写入内容很危险(可能存放重要的系统数据或代码),如果我们需要向内存空间写入数据时要使用操作系统分配的空间。(可以在操作系统下安全,规矩地编程,也可以自由地用汇编语言操作硬件)
DOS模式下,0:200~0:2ff没有系统或其他程序的数据或代码,我们可以使用这段空间。
5.8
参见P121程序5.9
6.1~6.2
程序6.3
assume cs:code
code segment
dw 0123h,0456h,0789h,0abch,0defh,0fedh,0cbah,0987h ---------用dw定义的数据,偏移地址为0,2,4,6,8,a,c, e;由于它们在代码段中,段地址在CS。
dw 0 ,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 ————用dw定义了16个字型数据,程序加载后取得16个字的内存空间存放这16个数据,在后面的程序中将这段空间当栈空间使用
(数据data)
start: —————程序入口
mov ax,cs ————第一个指令
mov ss,ax
mov sp30h (栈顶ss:sp指向cs:30)
mov bx,0
mov,cx,8
s: push cs:[bx]
add bx,2
loop s (将0~15单元的八个字型数据依次入栈)
mov bx,0
mov,cx,8
s0: pop cs:[bx]
add bx,2
loop s0 (依次出栈到代码段的0~15单元中)
mov ax,4c00h
int 21h
code ends
end start
6.3
程序6..4
assume cs:code,ds:data,ss:stack 定义多个段:“code”,“data”,“stack”为段名(可随意取名,a,b,c都行)
data segment
dw 0123h,0456h,0789h,0abch,0defh,0fedh,0cbah,0987h data段
data ends
stack segment
dw 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 stack段
stack ends
code segment code段
start:(可以改名,比如D:则最后end D)
mov ax,stack 意为将名称为“stack”的段的段地址送入ax,。
mov ss,ax
mov sp,20h ss:sp即栈顶指向stack:20(20-2=1d,.........)
mov ax,data
mov ds,ax
mov bx,0 ds:bx指向data段的第一个单元
mov cx,8
s: push [bx]
add bx,2
loop s 将data段0~15单元的8个字型数据入栈
mov cx,8
s0: pop [bx]
add bx,2
loop s0 依次出栈到data段的0~15单元
mov ax,4c00h
int 21h
code ends
end start
(cpu真正执行的是start~end start之间的代码)
7.1~7.6
mov al,01100011b
and al,00111011b(逻辑与指令,结果:al=00100011b)
mov al,01100011b
or al,00111011b(逻辑或指令,结果:al=0111011b)
由上得大写,小写字母在ASCLL码的区别在于第5位数字是0还是1。
因此:可用and al,11011111b或or al,00100000b将字母变成大写\小写。(如果原本就符合则不变)
[bx+idata]表示一个内存单元的偏移地址((bx)+idata)常用格式例:[200+bx], 200[bx], [bx].200。
7.7~7.9
si,di寄存器和bx功能相近,但不能分成两个8位寄存器使用。
[bx+si]和[bx+di]可写为[bx][si]和[bx][di]
内存空间偏移地址还可以如下表示
7.10
用dx暂时保存cx中循环次数(有局限性:当所有寄存器都工作时——凉凉)
于是我们可以使用内存暂存数据,这时我们最好使用栈(不使用则需要记住内存空间位置)。
P158
8.1~8.3
bp寄存器的默认段地址为ss
tips:[bp+bx]是错误的。
P164,8.4
8.5
8086CPU可以处理两种尺寸数据:byte(8位),word(16位)
通过寄存器名指明处理的数据尺寸如al,ax。
指明内存单元长度:byte ptr和word ptr
8.6略
8.7、8.8
div除法指令:有8位16位两种。
被除数默认放在AX或DX和AX中。(如果除数为8位,被除数则为16位存放于AX,如果除数为16位,被除数则为32位,DX存放高16位AX存放低16位)
结果:除数为8位:al存放商,ah存放余数;除数为16位,ax存放商,dx存放余数。
db,dw,dd分别定义字节型,字型,双字型数据。
例P170,
P171分析
8.9
dup用于数据的重复,用法:
例:db 3 dup('abc','ABC')定义了18个字节即:abcABCabcABCabcABC。