汇编网首页登录博客注册
taotling的学习博客
博客首页博客互动【做检测题】论坛求助

我的博客

个人首页 |  我的文章 |  我的相册 |  我的好友 |  最新访客 |  文章收藏 |  论坛提问 |  友情链接 |  给我留言  
图片载入中
  •  有许多事,让DEBUG洗过更明白; 天真如我,学习汇编,以为撑得住未来; 而谁担保芯永远不会染上尘埃...
  • 『姓名』:TAOT                
  • 『性别』:保密  『发送消息
  • 个人说明:
  • 详细信息『加为好友』
学习动态
好友圈
文章收藏
友情链接

[2008-02-22 03:27] 13~14天学习笔记

1.若要使程序中的jmp指令执行后,CS:IP指向程序的第一条指令,
在datasg段中应该定义哪些数据?
================CODE=================================
assume cs:codesg
datasg segment
        ......
datasg ends

codesg segment
  start:        
                mov ax,datasg
                mov ds,ax
                mov bx,0
                jmp word ptr [bx+1]
codesg ends
end start
=======================================================


分析:        
        若jmp word ptr [bx+1]执行后,CS:IP指向程序的第一条指令,
        (1)确定IP:那么IP这个偏移量应为零。即内存内容为:
                DS:0000~0002        ?? 00 00        (??处为随便占一字节的内容)
        (2)确定CS:因为是属于段内转移,所以CS不用指定。
        (3)datasg处定义为:
                db 0,0,0
                或
                db 0
                dw 0
当然,如果将jmp word ptr [bx+1]段内跳转指令改为
                    jmp dword ptr [bx+1],段间跳转指令又怎么办呢?
分析:        
        若jmp dword ptr [bx+1]执行后,CS:IP指向程序的第一条指令,
        (1)确定IP:那么IP这个偏移量应为零。即内存内容为:
                DS:0000~0002        ?? 00 00
        (2)确定CS:因为是属于段间转移,所以(CS)=(bx+1+2),即内存内容为:
                DS:0000~0005        ?? 00 00 CS(L) CS(H)
                那么如何把CS写到datasg中相应位置呢?用codesg或seg codesg。

                如下:

================CODE=================================
assume cs:codesg,ds:datasg

datasg segment
        db 0
        dw 0,seg codesg
datasg ends

codesg segment
start:
        mov ax,datasg
        mov ds,ax
        mov bx,0
        jmp dword ptr [bx+1]

        mov ax,4c00H
        int 21H
codesg ends
end start
======================================================

2.使jmp指令执行后,CS:IP指向程序的第一条指令。
======================CODE================================
assume cs:codesg,ds:datasg

datasg segment
        dd 12345678H
datasg ends

codesg segment
start:
        mov ax,datasg
        mov ds,ax
        mov bx,0
        mov [bx],bx
        mov [bx+2],cs
        jmp dword ptr ds:[0]

        mov ax,4c00H
        int 21H
codesg ends
end start
======================================================
分析:        
        若jmp dword ptr ds:[0]执行后,CS:IP指向程序的第一条指令,
        (1)确定IP:那么IP这个偏移量应为零。即DS处原内容为:
                DS:0000~0001        78 56
                应改为:
                DS:0000~0001    00 00
                这由"mov [bx],bx"来实现,
                当然也可以用"mov [bx],word ptr 0"来实现。
        (2)确定CS:因为是属于段间转移,所以(CS)=(DS:[bx+2]),即内存内容为:
                DS:0000~0004        78   56   34    12
                DS:0000~0004    00   00   CS(L) CS(H)
                这里由"mov [bx+2],cs"来实现;
                也可由"mov word ptr [bx+2],codesg"来实现。

                "mov [bx+2],codesg"和"mov [bx+2],word ptr codesg"均会出现警告性错误提示:
                        1702.ASM(13): warning A4031: Operand types must match
                        49004 + 431492 Bytes symbol space free

                          1 Warning Errors
                          0 Severe  Errors
                但还能编译够链接通过得到可执行文件,进行调试,也没问题。


3.在内存2000H段中查找第一个值为0的byte,
  找到后,将它的偏移地址存储在dx中。
=============================CODE=========================
assume cs:code
code segment
  start:
        mov ax,2000h
        mov ds,ax
        mov bx,0
        s:
                        mov cl,[bx]
                        mov ch,0
                        inc bx
        loop s
     
                ok:
                        dec bx
                        mov dx,bx
                mov ax,4c00h
                int 21h
code ends
end start
======================================================
如果程序是这样,那么当遇到第一个0的时候,
程序运行到loop处CX已经为零。
程序执行loop,首先要CX-1 = 0000-1 = FFFF,使得CX = FFFF,
然后判断CX,不为零,程序会继续执行,而不跳出loop。

经过debug还可以发现,上面的程序是对"遇到第一个1的时候"的解决方案,
而不是"遇到第一个0的时候的解决方案"。

所以要解决这种特殊问题,那我们在遇到loop进行CX-1之前,
给CX其加上1,就可以了。

改后程序如下:

=============================CODE=========================
assume cs:code
code segment
  start:
        mov ax,2000h
        mov ds,ax
        mov bx,0
        s:
                        mov ch,0
                        mov cl,[bx]
                        inc cx
                        inc bx
        loop s
     
                ok:
                        dec bx
                        mov dx,bx
                mov ax,4c00h
                int 21h
code ends
end start
======================================================


4.(实验8)下面程序能否正确返回:
=========================CODE=============================
assume cs:codesg
codesg segment
        mov ax,4c00H
        int 21H
  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

IF 0
***************************************************************************
源程序                        CS:[XXXX]        指令所                对应机器码                  Debug下u命令
                                  地址           占字节数         (按所占内存位置)                对应指令
assume cs:codesg
codesg segment

mov ax,4c00H          [0000]         [3]                  B8 00 0C                        MOV AX,4C00                        
int 21H                          [0003]         [2]                  CD 21                                INT 21
start:
mov ax,0              [0005]         [3]                  B8 00 00                        MOV AX,0000
s:
nop                                  [0008]         [1]                  90                                NOP
nop                              [0009]         [1]                  90                                NOP
mov di,offset s   [000A]         [3]                  BF 08 00                        MOV DI,0008
mov si,offset s2  [000D]         [3]                  BE 20 20                        MOV SI,0020
mov ax,cs:[si]          [0010]         [3]                  2E                                CS:
                                                                                  8B 04                                MOV AX,[SI]
mov cs:[di],ax          [0013]         [3]                  2E                                CS:
                                                                                  89 05                                MOV [DI],AX
s0:
jmp short s              [0016]         [2]                  EB F0                                JMP 0008
s1:
mov ax,0              [0018]         [3]                  B8 00 00                        MOV AX,0000
int 21H                      [001B]         [2]                  CD 21                                INT 21
mov ax,0              [001D]         [3]                  B8 00 00                        MOV AX,0000
s2:
jmp short s1          [0020]         [2]                  EB F6                                JMP 0018
nop                          [0022]         [1]                  90                                NOP
codesg ends
end start
*****************************************************************************
装载的时候,IP=5。
即装载程序后,CS:IP为CS:0005,从start处的mov ax,0开始执行指令。
mov ax,0                        (AX)=0

s:                                        s标号

nop                                        占位1字节;
nop                                        占位1字节;

mov di,offset s                (DI) = 0008H,因为"offset s"是s处相对于CS:0000H处的偏移值;

mov si,offset s2        (SI) = 0020H,因为"offset s2"是s2处相对于CS:0000H处的偏移值;

mov ax,cs:[si]                (AX) = (CS:0020H),也就是AX的内容为CS:0020H处起始的两个字节的内容;
                                        而CS:0020H处开始的两个字节的内容为jmp short s1,
                                        那么我们来看看jmp short s1的实质是什么:
                                        jmp short "标号"的的功能是修改IP,使得(IP)=(IP)+位移量(8位)
                                        这种不带目的地址的指令转移指令,是靠位移量对IP修改进行的。
                                        位移量 = ”标号“处的地址 - jmp指令后的第一个字节的地址,即:
                                        位移量 = 18H - 22H = F6(用8位来表示),
                                        这是个负数,用补码表示为:11110110,表示位移是向上移动。
                                        根据"负数的补码取反加1得其绝对值",
                                        这个负数的绝对值为:          00001010
                                        也就是16进制的A,十进制的10。        
                                        也就是说jmp short s1的实质是要使得(IP)=(IP-AH)
                                        这jmp short s1被编译器编译后,就已算出,
                                        所以编译后,s1已经被转为偏移值了。
                                        我们可看到"jmp short s1"对应的机器码为:EB F6

mov cs:[di],ax                把(AX)也就是(CS:0020H)的内容(EB F6)写到CS:[DI]处,
                                        也就是s标号处的两个nop字节被改为了EB F6。

s0:                                s0标号

jmp short s                        对应机器码为EB F0,
                                        F0十进制绝对值为16,即为10H,也就是改变IP,使得(IP)=(IP) - 10H,
                                        当CPU读取EBF0并将其送入指令缓冲器后,IP为0018H,
                                        而执行完EBF0后,IP = 0018H - 10H = 0008H
                                        即跳到S标号地址处。

EBF6(原nop nop)                此时这里已经被上面执行过的指令改写为EBF6,
                                        而EBF6的指令使得(IP)=(IP-AH)
                                        CPU读入EBF6并将其送入指令缓冲器后,IP为000AH
                                        而执行完EBF0后,IP = 000AH - 000AH = 0000H

mov ax,4c00H
int 21H                                这两条指令能使程序正确返回。
                                        
*****************************************************************************************
ENDIF


5.下面指令执行到mov ax,4c00H之前时,AX值为多少?
*******************************************************
assume cs:codesg

codesg segment
start:
        mov ax,2  
        mov cx,3  
        
        s: 
                add ax,2  
        s1:        loop s  
                mov di,offset s1  
                mov si,offset s3  
                mov ax,cs:[di]  
                mov cs:[si],ax  
                
                mov ax,1  
                mov cx,3  
        s2: 
                add ax,2  
        s3: 
                nop  
                nop  
        
        mov ax,4c00H
        int 21H
codesg ends
end start
*******************************************************
分析:
s:        add ax,2  
s1:        
        loop s  

        mov di,offset s1  
        mov si,offset s3  
        mov ax,cs:[di]  
        mov cs:[si],ax                此4条指令是将标号为s1处的指令(loop s)复制到s3处。
                                                loop s编译后占两字节。
                                                loop s编译后,实际上为是一种带CX值判断的jmp short 标号指令。
                                                也可以说是与"jcxz 标号"指令恰好相反的指令。
                                                所以是属于带偏移值的跳转指令,我们来看跳转的是多少。
                                                loop s 本身占2,s标号处的add ax,2占3,
                                                如果s处地址为CS:000YH的话,
                                                那么loop s指令后的第一个字节地址为:CS:000XH
                                                其中:X = Y+3+2
                                                所以jmp short的偏移值为:Y - X = Y-y-3-2 = -5。
                                                
                                                所以,上面4条指令所复制的机器码实际上的功能是使得:
                                                (1)判断CX-1是否等于0;
                                                (2)如果CX-1为零,那么对(IP)不做修改。
                                                (3)如果CX-1不为零,那么(IP)=(IP)-5 。


        mov ax,1            重新赋值ax。
        mov cx,3                        
s2:
        add ax,2  
s3:
        nop                                                                        
        nop                                        实际上这两个nop被改为:
                                                (1)判断CX-1是否等于0;
                                                (2)如果CX-1为零,那么对(IP)不做修改。
                                                (3)如果CX-1不为零,那么(IP)=(IP)-5 。
                                                所以相当于loop s2了。
                                                所以,ax到这里为7。
评论次数(2)  |  浏览次数(1190)  |  类型(学习笔记) |  收藏此文  | 

[  jhszcn   发表于  2008-03-30 09:40  ]

精辟,学习

[  mengxinjinglong   发表于  2008-11-10 07:43  ]

学习了

 
 请输入验证码  (提示:点击验证码输入框,以获取验证码