转载必须注明出处,违者必究。http://www.cnblogs.com/dennisOne
debug和汇编编译器masm对指令的不同处理
-
debug
-
masm
-
debug和编译器对[idata]有这不同的解释。
debug将"[idata]"是一个内存单元,"idata"是内存单元的偏移地址;而编译器将"[idata]"解释为"idata"。
-
解决之道
可以使用两种方式解决:
(1). 指定段地址
mov al,ds:[0] 含义:(al)=((ds)*16+0),将内存单元中的数据送入al中;
mov al,ds:[bx]含义:(al)=((ds)*16+(bx)),将内存单元中的数据送入al中。
(2). 使用[bx]
mov al,[bx] 含义:同"mov al, ds:[bx]"相同。
loop指令
- 指令格式: loop 标号
-
CPU在执行loop指令要进行两步操作:
(1). (cx) = (cx)-1
(2). 判断cx中的值,不为零则转至标号处执行程序,如果为0则向下执行。
-
loop指令的基本结构
计算:2^12
1 assume cs:code 2 code segment 3 start: mov ax, 2 4 mov cx, 11 5 s: add ax, ax 6 loop s 7 8 mov ax, 4c00h 9 int 21h 10 code ends 11 end start
loop指令等价于C的do…while结构: cx = 循环次数; do { // 循环体 cx--; } while (cx);
loop和[bx]的联合使用
例:计算ffff:0-ffff:b单元中的数据的和,结果储存在dx中。
1 assume cs:code 2 code segment 3 mov ax, 0ffffh 4 mov ds, ax 5 mov bx, 0 ; 初始化ds:bx指向ffff:0 6 7 mov dx, 0 ; 初始化累加寄存器dx, (dx)=0 8 mov cx, 12 ; 设置循环计数寄存器cx, (cx)=12 9 10 s: mov al, [bx] 11 mov ah, 0 12 add dx, ax ; 指令的寄存器的位数必须匹配 13 inc bx ; ds:bx指向下一个单元 14 loop s 15 16 mov ax, 4c00h 17 int 21h 18 19 code ends 20 21 end
段前缀
-
显式地指明内存单元的段地址的"ds:","cs:","ss:","es",在汇编语言中称为段前缀。
1 mov ax, ds:[bx] 2 mov ax, cs:[bx] 3 mov ax, ss:[bx] 4 mov ax, es:[bx] 5 mov ax, ds:[0] 6 mov ax, cs:[0] 7 mov ax, ss:[0] 8 mov ax, es:[0]
-
段前缀的使用
例:将内存ffff:0~ffff:b单元中的数据复制到0:200~0:20b单元中。
1 assume cs:code 2 3 code segment 4 start: mov ax, 0ffffh 5 mov ds, ax ;(ds)=0ffffh 6 7 mov ax, 20h 8 mov es, ax ;(es)=0020h 9 10 mov bx, 0 ;ds:bx指向ffff:0, es:bx指向0020:0 11 12 mov cx, 12 ;(cx)=12, 循环12次 13 14 s: mov dl, ds:[bx] 15 mov es:[bx], dl 16 inc bx 17 loop s 18 19 mov ax, 4c00h 20 int 21h 21 22 code ends 23 end start
一段安全的空间
在8086实模式中,随意向一段内存空间写入内容是危险的,因为这段空间可能存放着重要的数据或者代码。
当然,我们是在操作系统的环境中工作,操作系统管理着所有的资源,当然包括内存。如果向内存空间写入数据时,要使用操作系统给我们分配的内存,而不应该用地址任意指定内存单元。
在一般的PC机中,DOS方式下,0:200~0:2ff的256个字节的空间是一段安全的空间。
来源:https://www.cnblogs.com/dennisOne/archive/2012/10/20/2732011.html