美文网首页汇编语言程序员汇编语言
<<汇编语言>>---王爽 检测点 10

<<汇编语言>>---王爽 检测点 10

作者: 王一航 | 来源:发表于2017-02-28 16:48 被阅读693次

    题目 :

    下面程序执行后 , ax 中的值是什么 ?

    assume cs:code,ss:stack
    stack segment
        dw 8 dup(0)
    stack ends
    code segment
        start:
            mov ax, stack
            mov ss, ax
            mov sp, 0010H
            mov ds, ax
            call word ptr ds:[0EH]
            inc ax
            inc ax
            inc ax
    code ends
    end start
    

    下面的程序执行后 , ax 和 bx 的值是什么 ?

    assume cs:code,ds:data
    data segment
        dw 8 dup(0)
    data ends
    code segment
        start:
            mov ax, data
            mov ss, ax
            mov sp, 16
            mov word ptr ss:[0], offset second
            mov ss:[2], cs
            call dword ptr ss:[0]
            nop
        second:
            mov ax, offset second
            sub ax, ss:[0CH]
            mov bx, cs
            sub bx, ss:[0EH]
    code ends
    end start
    

    分析 :

    第一题 :

    该题中的程序的数据段和栈段使用了同一段内存 , 也就是说 ds 和 ss 是相同的
    执行到 call word ptr ds:[0EH] 的时候 , 具体的流程如下 : 
    1. CPU取指令 : (call word ptr ds:[0EH])
    2. ip自增上述指令的长度 , 指向了下一条指令 (inc ax)
    3. 开始执行该指令
      3.1. push ip ; 将 ip 压入栈 , 也就是 : ss:[0EH] 保存 ip 的低 8 位 , ss:[0FH] 保存高 8 位
      3.2. jmp ds:[0EH] ( (ip) = ds:[0EH] , 也就是说 , 程序又从 ds:[0EH] 中取出数据赋值给 ip , 然后继续执行 )
    4. 现在其实就开始执行 ip 之前保存的地址的指令了 , 也就是三个 inc ax
    5. 因此最终 ax 值为 3  
    

    第二题 :

    这个程序定义了数据段 , 其实也是栈段和数据段使用了同一段内存
    首先也是初始化栈 : 
    mov ax, data
    mov ss, ax
    mov sp, 16
    然后执行 : 
    mov word ptr ss:[0], offset s
    将 s 标号处两个字节的地址移动到 ss:[0] 处
    mov ss:[2], cs
    将代码段地址的值保存在到 ss:[2] 处 , 同样两个字节
    call dword ptr ss:[0]
    CPU首先读取该指令
    然后将 ip 增加该指令的长度
    然后准备开始执行 (由于是 dword 因此 cs 和 ip 都要压栈)
    执行首先要将当前的 cs 压栈 (保存在 ss:[0EH])
    然后 ip (也就是 call 指令下一个指令的地址 , 也就是 nop 的地址) 压栈 (保存在 ss:[0CH]) 处
    然后读取 ss:[0] 中的四个字节的数据 , 相当于 : 高地址为段地址 , 低地址为偏移地址
    也就说 cs 为 (ss:[2]) , ip 为 (ss:[0])
    这个 cs 和 ip 组成的地址就是 second 的地址
    现在开始执行 second
    mov ax, offset second
    读指令 , ip自增 , 然后执行 , 因此执行完后 , ax 为该指令的偏移地址
    然后 sub ax, ss:[0CH]
    通过之前的分析 : 
    ss:[0CH] 处保存的是 : call dword ptr ss:[0] 这条指令的下一条指令 nop 的相对于代码段偏移地址
    ax = (mov ax, offset second 的偏移地址) - ( nop 的偏移地址)
    也就是 nop 指令的长度 , 也就是 1
    接下来 : 
    mov bx, cs
    将代码段的基址赋值给 bx
    bx = (bx) - (ss:[0EH])
    (ss:[0EH]) = (cs)
    因此 bx = 0
    

    相关文章

      网友评论

        本文标题:<<汇编语言>>---王爽 检测点 10

        本文链接:https://www.haomeiwen.com/subject/mujxgttx.html