汇编语言 复习第九章(转移指令的原理)

 

第九章是 转移指令的原理

可以修改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)=8cs: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

 

posted @ 2013-06-30 20:39  Geekers  阅读(387)  评论(0编辑  收藏  举报