本文共 5283 字,大约阅读时间需要 17 分钟。
EAX、EBX、ECX
和 EDX
的高两位字节和低两位字节
可以独立使用,E 为 Extended 表示 32 位的寄存器;例如 EAX 的低两位字节称为 AX,而 AX 的高低字节又可分别作为两个 8 位寄存器,分别称 AH 和 AL。寄存器的名称大小写都可以。除 EBP 和 ESP 外,其他几个寄存器的用途是比较任意的mov
为例,mov 用于在内存和寄存器
之间移动数据,它有两个参数:第一个是目的地地址,第二个是源地址
,示例如下:mov eax, [ebx] ;将 ebx 值指示的内存地址中的 4 字节传送到 eax mov [var], ebx ;将 ebx 值传送到 var 的值指示的内存地址中 mov eax, [esi-4] ;将 esi-4 值指示的内存地址中的 4 字节传送到 eax mov [esi+eax], cl; mov edx, [esi+4*ebx];
注意:最多只能利用两个 32 位寄存器和一个 32 位的有符号常数相加计算出一个内存地址
。
DB(D 表示 Data,B 表示 Byte)、DW(W 表示 Word,2Bytes)和DD(第二个字母 D 表示 Double World,4Bytes)
,这样就能指导编译器分配内存空间,但是对于:mov [ebx], 2;
BYTE PTR, WORD PTR 和 DWORD PTR
,则上述例子可写成:mov byte ptr [ebx], 2; 将 2 以单字节形式传输到 ebx 值指示的内存地址中 mov word ptr [ebx], 2; 将 2 以双字节的形式传送到 ebx 值指示的内存地址中 mov dword ptr [ebx], 2; 将 2 以四字节的形式传送到 ebx 值指示的内存地址中
数据传送指令、逻辑计算指令和控制流指令
。 以下用于操作数的标记分别表示寄存器、内存和常数::表示任意寄存器,若其后带有数字,则指定其位数,如 表示 32 位寄存器(EAX,EBX,ECX,EDX,ESI,EDI,ESP 或 EBP); 表示 16 位寄存器(AX, BX, CX 或 DX); 表示 8 位寄存器(AH、AL、BH、BL、CH、CL、DH、DL)。 :表示内存地址 :表示 8 位、16 位或 32 位常数, 表示 8 位常数。
mov ax,; 机器码为 B8H mov al, ; 机器码为 B0H mov / , ; 机器码为 89H mov , / ; 机器码为 8AH mov , / ; 机器码为 8BH
寄存器的内容、内存中的内容或常数值
,复制到第一个操作数——寄存器或内存
,但不能用于直接从内存复制到内存
,语法如下:mov, mov , mov , mov , mov , example: mov eax, ebx; mov byte ptr [var], 5;
将操作数压入内存的栈
,常用于函数调用。ESP 是栈顶
,压栈前先将 ESP 值减 4
,因为栈增长方向与内存地址增长方向相反
,然后将操作数压入 ESP 指示的地址;栈中元素固定为 32 位。语法:pushpush push example: push eax; push [var]; 将 var 指示的内存地址的 4 字节值压入栈
执行出栈
工作,出栈前先将 ESP 指示的地址种内容取出栈,然后将 ESP 值加 4,语法如下:pop edi; 弹出栈顶元素送到 edi pop [ebx]; 弹出栈顶元素送到 ebx 值指示的内存地址的 4 字节中
两个操作数相加
,相加的结果保存到第一个操作数
中。sub 指令用于两个操作数相减
,相减的结果保存到第一个操作数中,语法格式入下:add, add , add , add , add , sub , sub , sub , sub , sub , example: sub eax, 10 ;eax ←eax-10 add byte ptr [var], 10 ;10 与 var 值指示的内存地址的一字节值相加,并将结果保存在与 var 值指示的内存地址的字节中
inc、dec 指令分别表示操作数自加 1、自减 1
,其语法格式如下:
incinc dec dec example: dec eax ;eax 值自减 1 inc dword ptr [var] ;var 值指示的内存地址的 4 字节值自加 1
带符号整数乘法指令
,有两种格式:1)两个操作数,将两个操作数相乘,并将结果保存在第一个操作数中,第一个操作数必须为寄存器
;2)三个操作数,将第二个和第三个操作数相乘,并将结果保存在第一个操作数中,第一个操作数必须为寄存器
;语法格式如下:imul, imul , imul , , imul , , example: imul eax, [var] ;eax←eax * [var] imul esi, edi, 25 ; esi←edi * 25
带符号整数除法指令
,只有一个操作数,即除数,而被除数则为 edx:eax 中的内容
,64 位整数;操作结果分为两部分:商和余数,商送到 eax,余数送到 edx
;语法格式如下:idividiv example: idiv ebx idiv dword ptr [var]
逻辑与、逻辑或、逻辑异或
操作指令,用于操作数的位操作
,操作结果放在第一个操作数
中;语法格式如下,由于格式类似,只需将前面的指令改一下就可以,所以这里以 and 为例:and, and , and , and , example: and eax, ofH ;将 eax 中的前28 位全部置零,最后 4 位不变 xor edx, edx ;置 edx 中的内容为
位翻转指令
,将操作数的每一位翻转,即0⟶1,1⟶0
;语法格式如下:notnot example: not byte ptr [var] ;将 var 值指示的内存地址的一字节的所有位翻转。
取负指令
,语法格式如下:negneg example: neg eax
逻辑位移指令,shr 为逻辑右移,shl 表示逻辑左移
,第一个操作数表示被操作数
,第二个操作数指示移位的位数
;语法格式如下:shl, shl , shl , shl , ; 上面的 shl 改成 shr 就是逻辑右移的格式 example shl eax, 1 ;将 eax 的值左移 1 位,相当乘于 2 shr ebx, cl ;将 ebx 值右移 n 位,n 为 cl 中的值,相当于除于 2^n
指令指针(IP)
,当执行一条指令后,此指针自动指向下一条指令。IP 寄存器不能直接操作
,但可以用控制流指令更新
。通常用标签(label)指示程序中的指令地址
,在 X86 汇编代码中,可在任何指令前加入标签
,例如:mov esi, [edp+8] begin: xor ecx, ecx mov eax, [esi]
控制 IP 转移到 label 所指示的地址
,从 label 中取出指令执行;语法格式如下:jmp
条件转移指令
,它依据处理机状态字
中的一系列条件状态
转移。处理机状态字包括指示最后一个算术运算结果是否为 0,运算结果是否为负数等;语法格式如下:je
比较两个操作数的值
,并根据比较结果设置处理机状态字中的条件码;语法格式如下:cmp, cmp , cmp , cmp ,
cmp dword ptr [var], 10 jne loop ;如果 var 指示的内存地址的 4 字节内容等于 10,则继续执行下一条指令;否则跳转到 loop 指示的指令执行。
子程序(过程、函数等)的调用及返回
。call 指令首先将当前指令地址入栈,然后无条件转移到由标签指示的指令。与其他简单的跳转指令不同,call 指令保存调用之前的地址信息,当 call 指令结束后,返回调用之前的地址。ret 指令实现子程序的返回机制,ret 指令弹出栈中保存的指令地址,然后无条件转移到保存的指令地址执行。call 和 ret 是函数调用中最关键的两条指令,其语法格式如下:callret
转载地址:http://ymqgn.baihongyu.com/