汇编要点汇总

  1. 循环执行的过程数组

  2. 分支执行过程ide

     

  3. stos=storagestring函数

4.c规范(函数堆栈操做)编码

    push ebpspa

    mov ebp,esp3d

    sub esp,0C0h指针

    push ebxcode

    push esiblog

    push ediip

       ...

    pop edi

    pop esi

    pop ebx

    mov esp,ebp

    pop ebp

5.带参函数(个数1),调用前:

    push ecx

  使用参数:

    mov eax,[ebp+8]

    为何是+8?这是由于call 会致使一条指令进栈,在加上函数开始时的push ebp,因此+8才能取到函数的参数

  函数结束:

  add esp,4

6.变长指令的问题,系统并非一次读入整条指令,而是先取指令的前面几位,再决定该次取指操做怎么进行

7.switch语句 基本上会出现cmp xxx je xxx 全部的分支判断都放在最前,后面是各分支要执行的内容

8.汇编里面没有枚举体和共用体,有的只是结构体和基础类型

9.数组的访问,一般你会碰到这样的代码

    mov eax,<我要取得数组元素的下标>

    imul eax,eax,<结构大小>

    mov ecx,<结构数组开始的地址>

    mov eax,dword ptr[ecx+eax];取数组元素内容放到eax

    Or 访问结构内部元素    

    mov ecx,dword ptr[ecx+eax+0Ch]

    这些汇编码都是解读时应该注意的标志性的代码

    二维数组转成汇编其实是一个结构体数组

10.阅读汇编码时,能够将代码进行分类,F(函数调用相关)   C(流程控制代码)   D(数据操做,四则运算)

11.发行版本的汇编代码,会尽可能去掉循环

12.若是返回值指向了在堆栈中开辟的内存,那么对该返回值的使用将会致使错误,由于堆栈中开辟的内存只在当前函数中有效

13.复杂类型(结构体,类)做为返回值时,先在函数外开辟内存,再将指针(eax)传入函数,函数返回时根据eax再在当前函数

   堆栈内存中作一份拷贝(也就是说当前堆栈中有两份一样的结构体实例)。

14.汇编指令的中括号表示偏移量,而且支持在中括号内的四则运算

15.远跳转是跨段跳转JMP or CALL

16.stos = store string

17.arpl=adjust prl

18.scas=search character among string

Compares the byte, word, or double word specified with the memory operand with the value in the AL, AX, or EAX register, and sets the status flags in the EFLAGS register according to the results. The memory operand address is read from either the ES:EDI or the ES:DI registers (depending on the address-size attribute of the instruction, 32 or 16, respectively). The ES segment cannot be overridden with a segment override prefix.

19. shr逻辑右移,左侧补0 sar算术右移左侧补符号位

20.test instructdent equal to and but it don't save the result only effect some bits of the flag register

21.IF中断标记位,响应中断时IF置为0,表示中断处理过程当中不响应可屏蔽中断(除非中断处理程序又将IF置为1(sti or cli)),而不可屏蔽中断只要发生cpu不会理睬IF标记位直接转到中断处理程序,不可屏蔽中断的中断类型码始终是2

22.汇编语句的结构必定程度上反映了cpu进行数据操做的方式,这也是理解和记忆汇编语句的简便方法。

23.有时候你须要显性的指出要访问的内存单元的长度,相似于mov ax,[0]这种语句,由于第一个操做数ax是一个字长,因此会从内存中取两个字节的数据放到ax中,for the mov al,[bx] cause the operand al represent only one byte's size, so the [bx] represent one byte data to be got from the memory, for some special conditions, you must indicate the size of the memory unit obviously, e.g. add byte ptr [bx],2, if we don't specify the size of memory data to be added, cpu will unknow the actual data to be added value 2. Such as inc byte ptr ds:[0] is the same.

24.关于进位和借位,cpu在作加法和减法会牵扯到这两种状况,固然若是运算结果在寄存器容量范围以内,则不会影响CF标志位,但若是一旦影响到CF标志位,咱们获得的结果是一个不彻底的结果,好比mov al,98H  add al,al最后结果是130H显然超出了al的容量,但因为进位信息保存在了标志寄存器中,因此咱们能够根据CF位的值连同al部分的值组合在一块儿来获得最终结果。此外cpu还直接提供了可以处理进位的加法指令adc和可以处理借位的减法指令sbb,实际上就是把进位标志带入到运算中,好比,adc ax,ax 等同于ax+ax+cf 原理相似于咱们作竖式运算的时候进位规则。

 简记CF(C,醋,无,无符号运算)  OF(O,有,有符号运算),两者互不影响,像add指令它既有无符号加法的含义又有有符号加法的含义,因此会同时影响这两个标志位。

25. pushf,popf让咱们有机会读取和修改标志寄存器中的内容。

26.那些个跳转指令i.e.那些影响CS IP寄存器的指令

 27.直接定址法

assume cs:code ds:data

data segment

a dw 2,3,5,89,29,2

b db 'sdsddsdsdsd'

table dw a,b

data ends

code segment

start:

code ends

end start

 注意上面几个标号,a b table它们后面没有冒号,这些标签直接表明了地址,使用的时候很像数组,a[bx],table[si]倒不是什么新的指令,只是以为汇编编译器逐渐向高级语言特性靠拢了,能够这么理解,a、b就是一些普通数组,table就是一个指针数组

28.mul指令 若是是8位相乘则结果放在ax中,16位相乘则结果放在dx和ax中,所以乘法不会产生溢出

div防溢出的办法,其实也很简单ffffffff/1结果是ffffffff确定要溢出的,由于一个16位的寄存器是放不下一个dword型数据的,那么咱们能够作下转化变为(ffff*ffff+ffff)/1=(ffff/1)*ffff+ffff/1分红两个不会溢出的除法,而后再求和。

29.jmpi指令 可同时改变cs and ip 格式:jmpi xxx(ip),xxx(cs) retn=ret near 格式 retn 0x0ch至关于pop ip;add esp,0x0ch

30.lea 指令 lea 寄存器,内存单元 意为load effective address 也就是内存单元的相对偏移地址。lea dx [ax+bx+5];dx=ax+bx+5其实至关于mov指令,但mov不支持操做数中.的四则运算,而lea能够,更省时,更有效率,有时还能够代替简单的加法。

31.算术加减乘除指令 or xor and 指令 以及shift指令都能影响标志位,进过实际操做证实, cmp以及test指令也能影响标志位,cmp主要是令两个操做数相减 而后设置一些标志位,set指令和jxx指令就是根据这些标志位的信息完成对应的操做。

相关文章
相关标签/搜索