X86机器码

 

OpCode(操作码) 和 mnemonic(助记符) 是多对多的

OpCode由6个域组成,其中code是必须的,其他是可选的

a. Prefixes b. code   c. ModR/M d. SIB e. Displacement f. Immediate

a. 前缀     b. 操作码 c. ModR/M d. SIB e. Displacement f. 立即数

 

AAM AL 除以 10 AL 商 AH 余数

AAD AL = AH * 10 + AL

 

EIP 存储了内存中的某个地址,这个地址告诉CPU,哪里是当前指令的开始,

但是在指令解码前,不知道哪里是指令的结束

1.

  00401000   90        NOP

  EIP        OpCode    mnemonic

  解码以后,由于知道NOP只有一个字节,EIP = EIP + 指令的长度(1+1)=00400001

2.

  00401000   EB 00     JMP 00401002

  00401002   90        NOP

  EB占用1个字节,00占用1个字节,EIP = EIP + 指令的长度(1+1)=00400002

3.

  00401000   EB FE     JMP 00401000

  00401002   90        NOP

  EB占用1个字节,FE占用1个字节,EIP = EIP + 指令的长度(1+1)=0xFE+0x2=0x100

  由于imm8的关系,0x100只能取00,2个字节的情况下,只能取低1个字节。

真正的底层程序员应该会理解指令的本质,而不仅仅是从指令的字面上去理解它的意思。

4.

  00401000   75 01    JNZ SHORT 3   -> 

                      如果不是0,那么EIP的值是 EIP当前值(00401000)

                      + 本条指令的立即数(01)+本条指令的长度(2)

  00401002   04 AC    ADD AL, 0AC

  所以会跳到04 AC的中间执行

Perfixes 前缀:

 1. 所有Prefixes的长度都是1个字节。

 2. 一个OpCode可能会有几个Prefixes。

 3. 如果有多个Prefixes,那么它们的顺序可以打乱。

 4. 如果Prefixes不能对随它之后的OpCode起作用,那么它就会被忽略。

Perfixes分类:

 1. Change DEFAULT operand size.(66)    切换默认操作数大小,是开关标记

 2. Change DEFAULT address size.(67)    切换默认地址的大小,是开关标记

 3. Repeat prefixes.(F2 F3)             重复前缀

 4. Segment override prefixes (change DEFAULT segment).

    2E - CS    36 - SS    3E - DS    26 - ES    64 - FS    65 - GS

 5. LOCK prefix.(F0)                    锁前缀

例:8A 00 MOV AL, [EAX] -> 67 8A 00 MOV AL, [BX+SI]

    地址由原来的32位的[EAX]变成了16位的[BX+SI]

    在16位的地址模式中无法完全使用32位中的对应的地址模式,

    两种模式中的寄存器有着一定的区别。

 

Repeat Prefixes(F2 F3)

Repeat Prefixes通常是与movs scas cmps 等串指令搭配使用

F2 REPNE    F3 REP/REPE

重复执行后面的串操作指令,每次重复前先判断(E)CX的值,> 0 把(E)CX的值减1,

再重复执行后面的串操作指令 =0退出

和LOOP指令的区别是:LOOP指令先把(E)CX的值减1,再判断是否为0

 

有3种Repeat Prefixes的助记符:rep/repe/repene,但是只有2个OpCode:F2 F3

如果某些指令只使用前缀rep,那么这里的rep可以用repe或者repne来代替

重复串指令时可能会改变某些标志位(例如ZF),在这种情况下,有些指令与重复前缀

搭配使用时,F2和F3会把最后一位与标志位ZF进行比较,

如果它们不相同,则重复串指令的操作将会结束。而有些指令不用进行这个比较的操作,

因此标志位ZF对这些指令的运行结果无影响。

11110010  F2    11110011  F3

Repeat Prefixes的结束条件    REP = ECX=0    REPE = ECX=0 && ZF=0    REPNE = ECX=0 && ZF=1

 

CS: For EIP pointer

ES: 目的操作数是内存单元的串指令(movs, cmps等),在这里源操作数是储存在段DS里面

SS: 堆栈操作(push, pop等)

DS: 剩下的数据操作指令

FS一般是由SEH(结构化异常处理)所使用

 

1个字节如果被转换成2进制,是由8bit来表示,不足8bit高位补0

ModR/M是由Mod Reg/Opcode R/M三个部分组成的

每个部分所占的bit大小为:

Mod:          6 7

Reg/Opcode: 3 4 5

R/M:        0 1 2

分析下面2条机器指令

8B F9(MOV EDI, ECX)         2B F9(SUB EDI, ECX)

因为没有前缀,F9是MOD Reg/OpCode R/M, F9(11111001)按照2:3:3拆开,

MOD=11

Reg/OpCode=111

           / 表示或,意思是这个地方可以表示为Reg或OpCode(由Code来决定),

             如果它是表示OpCode,则这个指令必定是2字节的。

           Reg由3个bit组成,所以有8种可能:

           000 - EAX    001 - ECX    010 - EDX    011 - EBX    100 - ESP

           101 - EBP    110 - ESI    111 - EDI

R/M=001

结论

Mod=11          表示应该查看Mod为11的那一栏

Reg/Opcode=111  表示的是寄存器EDI

R/M=001         表示的是ECX

 

你可能感兴趣的:(asm)