曲曲的秘密学术基地

纯化欲望、坚持严肃性

欢迎!我是曲泽慧(@zququ),目前在深圳(ICBI,BCBDI,SIAT)任职助理研究员。


病毒学、免疫学及结构生物学背景,可以在 RG 上找到我已发表的论文

本站自2019年7月已访问web counter

汇编语言 10.4 10.5 10.6 转移的目的地址在指令,寄存器以及内存中的call指令

10.4 转移的目的地址在指令中的call指令

前面讲的call指令,其对应的及其指令中并没有转移的目的地址,而是相对于当前IP的转移位移。

“call far ptr 标号”实现的是段间转移。

CPU执行此种格式的call指令时,进行如下的操作。

  1. (sp)=(sp)-2
    ((ss)*16+(sp))=(CS)
    (sp)=(sp)-2
    ((ss)*16+(sp))=(IP)

  2. (CS)=标号所在段的段地址
    (IP)=标号在段中的偏移地址

从上面的描述中可以看出,如果我们用汇编语法来解释此种格式的call指令,则:

CPU执行”call far ptr 标号”时,相当于进行:

push CS
push IP
jmp far ptr 标号

问题:

下面的程序执行后,ax中的数值为多少?

  内存地址 机器码 汇编指令
1 1000:0 b80000 mov ax, 0
2 1000:3 9A09000010 call far ptr s
3 1000:8 40 inc ax
4 1000:9 58 s:pop ax
5     add ax, ax
6     pop bx
7     add ax, bx

在1处,ax –> 0,在2处,执行call指令,IP = 8,并跳转到5处,pop ax,弹出IP地址并赋值给ax,此时ax –> 8。执行add ax, ax,ax –> 8 + 8 = 16 (注意这里是错误的,因为IP地址间的运算应该为16进制运算:8h + 8h = 10h)。由于call指令为call far ptr 标号实现的是段间转移,所以首先push的地址为CS,而后push进栈的地址为IP,所以第一次pop出的为IP,而后pop出的为CS。所以pop bx会弹出CS地址并赋值给bx,所以这是,bx的值为1000,所以add ax, bx –> ax = ax + bx = 10h + 1000h = 1010h。

10.5 转移地址在寄存器中的call指令

指令格式:call 16位reg
功能:

(sp)=(sp)-2
((ss)*16)+(sp)=(IP)
(IP)=(16位reg)

用汇编语法来解释此种格式的call指令,CPU执行”call 16位reg”时,相当于进行:

push IP
jmp 16位reg

问题:

下面的程序执行后,ax中的数值为多少?

  内存地址 机器码 汇编指令
1 1000:0 b80600 mov ax, 6
2 1000:3 ffd0 call ax
3 1000:5 40 inc ax
4 1000:6   mov bp, sp
5     add ax, [bp]

在1处,ax –> 6,在2处执行call ax指令,将IP = 5推入栈中,并跳转到ax对应的值为IP的地址,即1000:6,执行mov bp, sp,此时的(sp) = (sp) - 2 = 0000h(栈顶) - 2 = fffeh并赋值给bp。并且此时[bp] = ss:[bp] = 5。所以执行add ax, [bp]后,ax = ax + [bp] = 6h + 5h = 0bh。

10.6 转移地址在内存中的call指令

转移地址在内存中的call指令有两种格式。

  1. call word ptr 内存单元地址
    用汇编语法来解释此种格式的call指令,则:
    CPU执行”call word ptr 内存单元地址”时,相当于进行:
    push IP
    jmp word ptr 内存单元地址

    代码示例,

    mov sp, 10h
    mov ax, 0123h
    mov ds:[0], ax
    call sord ptr ds:[0]

    执行后,(IP) = 0123H,(sp)=0EH。

  2. call dword ptr 内存单元地址
    用汇编语法来解释此种格式的call指令,则:
    CPU执行”call dword ptr 内存单元地址”时,相当于进行:

    push CS
    push IP
    jmp dword ptr 内存那单元地址

    代码示例,

    mov sp, 10h
    mov ax, 0123h
    mov ds:[0], ax
    mov word ptr ds:[2], 0
    call dword ptr ds:[0]

    执行后,(CS)=0,(IP)=123H,(sp)=0CH。

问题(1):

下面的程序执行后,ax中的数值为多少?

assume cs:code
stack segment
  dw 8 dup (0)
stack ends
code segment
  start:mov ax, stack
        mov sp, ax
        mov sp, 16
        mov ds, ax
        mov ax, 0
        call word ptr ds:[0EH]
        inc ax
        inc ax
        inc ax
        mov ax, 4c00h
        int 21h
code ends
end start

首先我们绘制一个对应地址的表格,

  内存地址 代码
1 0C50:0000 mov ax, stack
2 0C50:0003 mov ss, ax
3 0C50:0005 mov sp, 16
4 0C50:0008 mov ds, ax
5 0C50:000A mov ax, 0
6 0C50:000D call word ptr ds:[0EH]
7 0C50:0011 inc ax
8   inc ax
9   inc ax
10   mov ax, 4c00h
11   int 21h

在5处,ax –> 0。在6处,执行call word ptr ds:[0EH],前面在3处,指明了栈顶为sp = 16,所以在栈顶的位置推入IP地址:IP = 0011,并执行跳转到目标地址ds:[0EH],正好指向刚刚推入栈的IP = 0011,所以ds:[0EH] = 0011,所以跳转到7处,执行三次inc ax,所以ax = 0 + 1 + 1 + 1 = 3。

问题(2)

下面的程序执行后,ax和bx中的数值为多少?

assume cs:code
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], 0ffset s
        mov ss:[2], cs
        call dword ptr ss:[0]
        nop
      s:mov ax, 0ffset s
        sub ax, ss:[0ch]
        mov bx, cs
        sub bx, ss:[0eh]
        mov ax, 4c00h
        int 21h
code ends
end start

根据代码绘制栈,

s的CS
s的IP-1
s的CS
s的IP

ss:[0]为s的IP,ss:[2]为s的CS。执行call dword ptr ss:[0]后,在ss:[0ch],ss:[0dh]处推入IP = s的IP - 1,并在ss:[0eh],ss:[0fh]推入CS = s的CS。在s中,mov ax, offset sax = s 的IP。执行sub ax, ss:[0ch],所以ax = ax - ss:[0ch] = s的IP - (s的IP - 1) = 1。mov bx, cs,所以bx = s的CS。则sub bx, ss:[0eh]结果,bx = s的CS - s的CS = 0。

Last One

C语言 如何利用mac xcode实现C语言反汇编

今天谈一下,如何利用mac系统下的xcode实现类似于windows系统下microsoft visual C++的反汇编功能。(1) 首先安装xcode(2) 按顺序在菜单栏目依次选择:file –> new –> Project…(3) 在新弹出的菜单栏中在最上面选择macos标签页下的Command Line Tool图标,如图所示:(4) 在新弹出的菜单栏中的Language选项栏中选择C,(5) 主界面上左侧菜单栏中会出现两个文件夹分别存放代码以及编译好的程序,(6)...…

C语言More
Next One

python 魔法方法 (4) 简单定制

整理自小甲鱼鱼C论坛简单定制下面来做一个案例,要求如下: 定制一个计时器的类 start和stop方法代表启动定时和停止计时 假设计时器对象t1,print(t1)和直接调用t1均显示结果 当计时器未启动或已经停止计时,调用stop方法会给予温馨的提示 像个计时器对象可以相加:t1+t2 只能使用提供的有限资源完成需要用到下面的资源: 使用time模块的localtime方法获取时间 time.localtime返回struct_time的时间格式 __str__()和_...…

pythonMore