转移指令原理
思维导图
根据位移进行转移的意义
在对应的机器码中不包含转移的目的地址,而包含的是到目的地址的位移。这种设计,方便了程序段在内存中的浮动装配。使程序装在内存中的不同位置都可正确执行,因为在执行时,只涉及到位移,而不是地址。如果是地址的话,程序没有装载到对应的位置,就会造成程序没有办法正确执行。
综合实验
实验8 分析一个奇怪的程序
分析下面的程序,在运行前思考:这个程序可以正确返回吗?
assume cs:codesg
codesg segment
mov ax,4c00h
int 21h
;反正就是刚好利用了jmp 的相对位移的特性.short 8位位移 = 标号处的地址-jmp指令后的第一个字节地址
start:
mov ax,0
s:
nop
nop
mov di,offset s
mov si,offset s2
mov ax,cs:[si]
mov cs:[di],ax
s0:
jmp short s
s1:
mov ax,0
int 21h
mov ax,0
s2:
jmp short s1
nop
codesg ends
end start
可以正确返回,刚好利用了jmp 的相对位移的特性.short 8位位移 = 标号处的地址-jmp指令后的第一个字节地址。当程序再次跳回到s标号处执行时,其第一条指令为 EBF6,就刚好是往上面跳到了 mov ax,4c00h
运行截图
实验9
在屏幕中间分别显示绿色\绿底红色\白底蓝色的字符串”welcome to masm!”.
代码
感觉这个没用到这章讲的东西啊??!!,还是因为我水平不行??
我是真的憨憨,第一开始没有注意到题目中说的是要在屏幕中间显示
改进前,写了三个循环
assume cs:codesg,ds:datasg
datasg segment
db 'welcome to masm!'
datasg ends
codesg segment
start:
mov ax,datasg
mov ds,ax
mov ax,0B800H
mov es,ax
;1
mov bx,6E0H
mov si,0
mov di,80
mov cx,16
s:
mov al,ds:[si]
mov es:[bx+di],al
mov byte ptr es:[bx+di+1],02H
add di,2
add si,1
loop s
;2
mov bx,780H
mov si,0
mov di,80
mov cx,16
s1:
mov al,ds:[si]
mov es:[bx+di],al
mov byte ptr es:[bx+di+1],24H
add di,2
add si,1
loop s1
;3
mov bx,820H
mov si,0
mov di,80
mov cx,16
s2:
mov al,ds:[si]
mov es:[bx+di],al
mov byte ptr es:[bx+di+1],71H
add di,2
add si,1
loop s2
mov ax,4c00h
int 21h
codesg ends
end start
改进后,写成了一个循环
assume cs:codesg,ds:datasg
datasg segment
db 'welcome to masm!'
db 02H,24H,71H
datasg ends
codesg segment
start:
mov ax,datasg
mov ds,ax
mov ax,0B800H
mov es,ax
;1
mov bx,6E0H
mov cx,3
mov bp,0
all:
push cx
mov si,0
mov di,80
mov cx,16
s:
mov al,ds:[si]
mov es:[bx+di],al
mov al,ds:[bp+16]
mov es:[bx+di+1],al
add di,2
add si,1
loop s
add bp,1
add bx,160
pop cx
loop all
; ;2
; mov bx,780H
; mov si,0
; mov di,80
; mov cx,16
; s1:
; mov al,ds:[si]
; mov es:[bx+di],al
; mov byte ptr es:[bx+di+1],24H
; add di,2
; add si,1
; loop s1
; ;3
; mov bx,820H
; mov si,0
; mov di,80
; mov cx,16
; s2:
; mov al,ds:[si]
; mov es:[bx+di],al
; mov byte ptr es:[bx+di+1],71H
; add di,2
; add si,1
; loop s2
mov ax,4c00h
int 21h
codesg ends
end start
运行截图
这个运行结果,怎么有的时候行有的时候不行?之前运行的时候,第一行的welcome 显示成了 celcome或是1/4elcome很奇怪。但是后面就又正常了