反汇编

第七部分 立即数

     立即数是Intel指令的中操作对象的一种(加上寄存器、内存共三种)。作为指令的一部分,立即数必须是直接可用的数字,这是立即数跟其他两种操作对象的主要区别(寄存器操作对象,CPU需要首先定位到寄存器,然后再读或写该寄存器中的对象。CPU指令的执行过程可粗分为:取指令,指令解码,取操作对象, ALU运算,存结果,取下一条指令……,立即数跟其他两种操作对象的区别体现在“取操作对象”这一步。立即数需要0个时钟周期,解码之后,立即数就可以使用了,立即立即,这就是立即的涵义所在;寄存器操作对象需要1个时钟周期;内存操作对象根据寻址方式的不同可能需要2-3或更多个时钟周期)。

7.1 立即数的解析

    立即数的解析相对来很简单。立即数有一些很明显的特性:
    1 立即数只有大小的分别。一般情况,我们也把改变EIP的指令中的常数作为立即数来处理。比如jmp rel8/16 或者 call 16:32……,这里相对偏移地址的大小与EIP/IP大小不一致的时候,一般需要进行符号位扩展。(前面曾经提到过指令的操作数大小一般必须相同,这点有特殊情况存在的,操作数大小扩展指令的操作对象就不一样,例如movcx, movzx, cwd, cdq等等指令)。

    
2 立即数只能做为源操作数而不能作为目的操作数。这点是很明确的,目的操作对象只能是寄存器或者内存。

    
立即数的解析只需要知道需要解析的立即数的大小就可以了,是几个字节读几个字节就行了。这里需要注意的一个重要的问题就是立即数需不需要进行符号为扩展的问题,或者更简单点来说,就是立即数是signed类型的还是unsigned的类型的。这就需要对指令的另外一个特殊的位进行解析了,那就是s位。

7.2 s

先来看看下面的一组指令:

    00401000      80C0 F8             add     al, 0F8
    00401003      81C0 78563412       add     eax, 12345678
    00401009      82C0 F8             add     al, -8    
实际为: add al, F8
    0040100C      83C0 F8             add     eax, -8    
实际为: add eax, FFFFFFF8

    
看看80818283指令的定义:(括号中表示ModR/M中的Reg/Opcode辅助编码部分)
    800  add  r/m8,    imm8
    81
0  add  r/m16/32/64,  imm16/32
    82
0  add  r/m8,    imm8
    83
0  add  r/m16/32/64,  imm8
    
    16/32
位的立即数不存在扩展之分,这里主要的区别在8位的立即数。很明显,82中的立即数是signed类型的,而80的是unsigned类型的,83实际为add eax, FFFFFFF8(因为指令的操作对象必须大小一致),需要把8位的立即数进行符号位扩展成32位。我们看看他们的编码区别:

    
指令   编码       非立即数操作对象大小  立即数
    ----------------------------------------------
    80  1000 00[0]0  8
    8(unsigned)   
    81  1000 00[0]1  16/32
    16/32
    82  1000 00[1]0  8    8(signed)    
    83  1000 00[1]1  16/32
    8(signed extern to 32)

    
这里我们首先能很明显地看到w位的存在,w位决定了内存编码的操作对象的

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值