实验3 转移指令跳转原理及其简单应用编程

实验任务1

代码功能简析

输出两行1 9 3
or 30h是为了转换为\(ASCII\)码输出。 \(30h\) 是ASCII中 \('0'\) 的编号,其二进制形式为:\(0011 0000\) ,所以or上一个 \(30h\) 表示输出从'0'开始偏移量为1 9 3的数字
如果 or 61h ,则输出的是偏移量减去 \(1\) 的小写字母。( \(61h\) 是 \(0110 0001\) ,从1开始)
$ 是预定义符号,表示当前的偏移地址,使用 jmp $ ,可以进入死循环。

问题1

实验3 转移指令跳转原理及其简单应用编程
反汇编查看机器码,可以看到其机器码为 \(E2F2\)
\(E2\) 表示LOOP
\(F0\) 是补码形式的位移量, \(F2\) 转换为二进制为 \(11110010\)
将其转换为原码 \(1!(1110010-1) = 1!(1110001) = 10001110 = -8+-4+-2=-14\)
所以其位移量为 \(-14\) 。当前ip为 \(0x19\) ,即 \(25\) ,\(25-14=11\)
但是s1处的偏移量为 \(D\) ,即 \(13\) 。
所以整个转移的过程如下
ip指向 \(25\) 偏移处的指令,先取指令,然后ip自动 \(+2\) ,变为 \(27\) ,然后执行指令的过程中,将ip减去 \(14\) ,得到 \(13\) ,那么下一条要执行的指令就在偏移量为 \(13\) 的地方,即s1标号处。

问题2

实验3 转移指令跳转原理及其简单应用编程

重复问题1的操作步骤。
\(F0\) 的二进制形式为: \(11110000\)
得到其原码: \(1!(1110000-1) = 1!(1101111) = 10010000 = -16\)
为什么指令数量相同,但是位移量不同?原因出在incadd的指令占字节数不同。8086汇编采用动态指令长度,所以每条指令的长度都不是相同的。所以这里会有位移量的不同。
CPU计算得到s2之后指令的地址方式和问题1一样,这里不重复描述。

实验任务2

代码简析

assume cs:code, ds:data
data segment
    dw 200h,0h,230h,0h
data ends

stack segment
    db 16 dup(0)
stack ends

code segment
start:
    mov ax,data
    mov ds,ax

    mov word ptr ds:[0],offset s1
    mov word ptr ds:[2],offset s2
    mov ds:[4],cs

    mov ax,stack
    mov ss,ax
    mov sp,16

    call word ptr ds:[0]
    ;push ip
    ;jmp word ptr ds:[0]
s1: pop ax
    ;(ax) = stack.top() = offset line23 + size(line23) = offset s1
    call dword ptr ds:[2]
    ;push cs
    ;push ip
    ;jmp dword ptr ds:[2]
s2: pop bx
    ;(bx) = stack.top() = offset line28 + size(line28) = offset s2
    pop cx
    ;(bx) = stack.top() = cs = code
    mov ah,4ch
    int 21h
code ends
end start
上一篇:Mac删除讨厌的.DS_Store文件夹


下一篇:DS顺序表合并操作