第九章是 转移指令的原理
可以修改IP,或者能够同时修改CS,IP的指令统称为转移指令
自己先说下吧,,,转移: 段内转移。(也就是CS不改变,段地址不改变,)
段间转移。
自己画个图
接着写,
1.操作符 offset(功能是取得标号的偏移地址)
2.jmp指令
3.jcxz指令
//jcsz 标号 (jcxz为有条件转移指令) 的功能用C语言相当于 if(cx == 0) { jmp short 标号 }
4.loop 指令(循环指令)
如果是和jcxz一起使用的时候,因为都要用到cx这个通用寄存器,所以要注意push和pop(入栈和出栈)
在后面的call 和ret 的使用,,也要非常注意 push 和 pop的使用。!!
5.根据位移进行转移的意义
这四个都是用位移来进行转移的。
这些汇编指令,他们对IP的修改是根据转移目的地址和转移其实地址之间的位移来进行的。
在他们对应的机器码中不包含转移的目的地址,而包含的是到目的地址的位移。
这种设计,方便了程序段在内存中的浮动装配。
6.编译器对转移地址超界的监测
编译器这个时候会报错的。
实验8
实验8 奇怪的程序// ps:这个程序是不会完全执行就返回的。 assume cs:codesg codesg segment mov ax,4c00h //三个字节 0 int 21h //二个字节 3 start: mov ax,0 ax=0 //三个字节 5 s: nop 占一字节,机器码90 8 nop 占一字节,机器码90 9 mov di,offset s (di)=s偏移地址 A mov si,offset s2 (si)=s2偏移地址 D mov ax,cs:[si] (ax)=jmp short s1指令对应的机器码EBF6 mov cs:[di],ax jmp short s1覆盖s处指令2条nop指令 s0: jmp short s 执行s???? 未执行到这里,直接跳回mov ax,4c00h了 s1: mov ax,0 int 21h mov ax,0 s2: jmp short s1 nop codesg ends end start P180中关于jmp指令的位移内容 当指令执行到s0:jmp short s时,该指令得到执行,编译器算出的ip位移量为8-18h=-16(补码F0),(ip)=(ip)+位移量=18h+(-16)=8,cs:8指向s; 当指令执行到s标段jmp命令时,第1个字节中的机器码为EBF6,给出的ip位移量为-10(补码F6),(ip)=(ip)+位移量=ah+(-10)=0,cs:0指向第一条指令。 C:\DOCUME~1\SNUSER>debug sy8.exe -u 0C4E:0005 B80000 MOV AX,0000 0C4E:0008 90 NOP 0C4E:0009 90 NOP 0C4E:000A BF0800 MOV DI,0008 0C4E:000D BE2000 MOV SI,0020 0C4E:0010 2E CS: 0C4E:0011 8B04 MOV AX,[SI] 0C4E:0013 2E CS: 0C4E:0014 8905 MOV [DI],AX 0C4E:0016 EBF0 JMP 0008 0C4E:0018 B80000 MOV AX,0000 0C4E:001B CD21 INT 21 0C4E:001D B80000 MOV AX,0000 0C4E:0020 EBF6 JMP 0018 0C4E:0022 90 NOP 0C4E:0023 FEFE ??? DH
检测点9.3 补全编程,利用loop指令,实现在内存2000H段中查找第一个值为0的字节,找到后,将它的偏移地址存储在dx中。 assume cs:code code segment start: mov ax,2000h mov ds,ax mov bx,0 s:mov cl,[bx] mov ch,0 inc cx inc bx loop s ok:dec bx mov dx,bx mov ax,4c00h int 21h code ends end start 书P101,执行loop s时,首先要将(cx)减1。 “loop 标号”相当于 dec cx if((cx)≠0) jmp short 标号
实验9 根据材料编程
编程:在屏幕中间分别显示绿色,绿色红底、白色蓝底的字符串‘welcome to masm!’
缓冲区在B8000H-BFFFFH 共32KB的空间,
为80X25的彩色字符模式的显示缓冲区,想这个地址空间写入数据,写入的内容将会立即出现在显示器上!
80个字符。。。(160个字节)BX,,AX通用寄存器双字节(一个字)
7 6 5 4 3 2 1 0
BL R G B I R G B
闪烁 背景色 高亮 前景色
一行总共用了160个字节(0A0H)
然后再算偏移量等等。
ax或者BX来存数据的话,ah高位存的是字符属性,地位存放的是字符。
代码如下:
assume cs:code data segment db 'welcome to masm!' data ends code segment start: mov ax,data mov ds,ax mov ax,0b800h mov es,ax mov bx,0720h ;设置中间行中间列的首地址 mov si,0 mov cx,16 s: mov ax,[si] mov ah,2h mov es:[bx],ax ;设置绿色字体 mov ah,24h mov es:[bx].0a0h,ax ;设置绿底红色 mov ah,71h mov es:[bx].0a0h.0a0h,ax ;设置白底蓝色, inc si ;指向下一字符 add bx,2 ;指向下一显存单元 loop s mov ax,4c00h int 21h code ends end start