汇编实验八 分析一个奇怪的程序

分析程序,在运行前思考:这个程序是否能够正确返回?
运行之后再思考:为什么是这种结果?
通过这个程序加深对相关内容的理解。

assueme 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

分析:

start: mov ax,0
    s: nop  ; nop标号语句,在运行时在代码段中分配一个字节的空间,
       nop  ; 这个字节(空间)的值为90h。
        
            ; 操作符 `offset` 的功能是取得标号的偏移地址。
       mov di,offset s   ;将 s 的偏移地址存到 di 寄存器中
       mov si,offset s2  ;将 s2 的偏移地址存到 si 寄存器中
       mov ax,cs:[si]    ;此行是将cs:[si]内存中的机器码存到ax寄存器中
                         ;这个机器码是由编译器将s2标号字段中的指令编译而成
       mov cs:[di],ax    ;将ax中的s2标号字段的机器码存放到s标号字段中
   s0: jmp short s       ;跳转到 s 标号字段处执行代码。

   s:  jmp short s1 ; 根据我们之前的分析, 指令是用相对偏移来表示的
    ; 因此执行的操作并不是真的跳转到 s1 这个标号, 
    ; 而是跳转编译时确定的 该指令到 s1 标号的偏移量。
    ; 所以我们要分析接下来程序的流程的话 , 就必须先编译程序 , 
    ; 通过查看这条指令的机器代码,才知道偏移量是多少。
    ; 然后再根据这个偏移量确定程序下一步应该执行哪里的指令。
    ; 根据下图的编译结果 , 可以发现 , 
    ; jmp short s1 在编译后得到的指令是 : EB F6
    ; 由上可知,偏移量是 :F6 
    ; 偏移量是由 补码 来表示的,由书中 附注二 ,
    ; 我们可以算出 F6对应的有符号十进制数为 -10。
    ; 从这里,我们可以知道,这条指令是将 ip 的值加上 -10。
    ; 那么,我们再看看 ip - 10 指向的地址是哪里呢 ? 
    ; 由下图的编译结果,我们可以知道,
    ; 它指向的刚好就是 code segment 开始的位置.
    mov ax,4c00h
    int 21h      ;看到这两句,大家就知道,程序是可以正常返回了
发布了20 篇原创文章 · 获赞 7 · 访问量 5806

猜你喜欢

转载自blog.csdn.net/weixin_43491622/article/details/84933940