操作符offset
在汇编语言中是由编译器处理的符号,它的功能是取得标号的偏移地址。
jmp指令
jmp为无条件转移,可以值修改IP,也可以同时修改CS和IP。
- jmp指令要给出两种信息:
- 转移的目的地址
- 转移的距离(段间转移、段内短转移、段内近转移)
- jmp short标号(转移到标号处执行指令):ip=ip+8
```
code segment
start:
mov ax,0
jmp short s
add ax,1
s: inc ax
mov ax,4c00H
int 21H
code ends end start
- jmp near ptr 标号 实现的是段内近转移:ip=ip+16
- jmp far ptr 标号 段间转移,又称远转移
- jmp word ptr 内存单元地址(段内转移)
- 从内存单元地址处存放着一个值,是转移的目的便宜地址
- jmp dword ptr 内存单元地址(段间转移)
- 从内存单元地址出开始存放这两个值,高地址处的值是转移的目的段地址,低地址出是转移的目的偏移地址。
<a name="bw0uZ"></a>
## jcxz指令
- 有条件转移指令,所有的有条件转移指令都是短转移,在对应的机器码中包含转移的位移,而不是目的地之。
- 指令格式:jcxz 标号
- 如果(cx)=0,则转移到标号出执行。
<a name="CH4oS"></a>
## call&ret指令
- call和ret指令都是转移指令,他们都修改ip,或同时修改cs和ip
- ret指令用栈中的数据,修改ip的内容,从而实现近转移
- cpu执行ret指令时
- (ip)=((ss)*16+(sp))
- (sp)=(sp)+2
- call指令经常跟ret指令配合使用,因此CPU执行call指令
- 将当亲的ip或cs和ip压入栈中
- 转移(jmp)
- call指令不能实现端转移,除此之外,call指令实现转移的方法和jmp指令的原理相同
- call 标号,相当于:
- push ip
- jmp near ptr 标号
code segment
start:
mov sp,10h
mov ax,0123h
mov ds:[0],ax
mov word ptr ds:[2],0
call dword ptr ds:[0]
mov ax,4c00H
int 21H
code ends end start
(cs)=0000,(ip)=0123,(sp)=0c
<a name="M7RRi"></a>
## mul命令
- mul是乘法命令
- 相乘的两个数:要么都是8位,要么都是16位
计算data段中数据的3次方:
data segment
dw 1,2,3,4,5,6,7,8
dw 0,0,0,0,0,0,0,0
data ends
code segment
start:
mov ax,data
mov ds,ax
xor bx,bx
mov cx,8h
xor si,si
s: mov ax,[bx]
mul [bx]
mul [bx]
mov [bx+10h],ax
add bx,2
loop s
mov ax,4c00H
int 21H
code ends end start
<a name="yGlHa"></a>
## 批量数据的传递
- 将data段中的字符串转化为大写
data segment
db ‘conversation’
data ends
code segment
start:
mov ax,data
mov ds,ax
mov cx,12d
mov si,0h
call capital
mov ax,4c00H
int 21H
capital:and byte ptr [si],11011111b inc si loop capital ret
code ends end start
<a name="VZDMk"></a>
## 寄存器冲突问题
- 讲一个全是字母,以0结尾的字符串,转化为大写
data segment
db ‘word’,0
db ‘unix’,0
db ‘wind’,0
db ‘good’,0
data ends
code segment
start:
mov ax,data
mov ds,ax
mov bx,0h
mov cx,4
s: mov si,bx
push cx
call capital
pop cx
add bx,5h
loop s
mov ax,4c00H
int 21H
capital:mov cl,[si] mov ch,0 jcxz ok and byte ptr [si],11011111b inc si jmp short capital
ok: ret
code ends
end start
```