nasm常用指令

mov

mov destination, source
移动数据到寄存器或者内存
移动ebx数据到eax
mov eax, ebx
移动 ebx+8 内存地址的4个字节数据到 eax
mov eax, [ebx+8]

movsx - 符号扩展移动,2个操作数大小不一样,比如16位移动到32位,32位要跟16位同符号

movzx - 0扩展移动,2个操作数大小不一样,比如16位移动到32位,32位的高16位填充0

lea(load effective address)

lea des, src

加载有效地址,假设 ebx = 0x00403A40,那么下面操作后,eax = 0x00403A48

lea eax, [ebx+8]

inc

inc destination

操作数增加1

dec

dec destination

操作数减1

add/sub

add/sub destination, source
Register to register
Memory to register
Register to memory
Register to constant data
Memory to constant data

加减指令,不允许 内存到内存 操作

adc

带进位加法,相当于 add x, x, CF,正常加法再加上进位标志位

mov dl, 0
mov al, ffh
add al, ffh
adc dl, 0     ;dl = 1, al = ffh, dlal = 01ffh

sbb

带进位减法,相当于多减去一个进位标志位的值

mul/imul

MUL/IMUL multiplier

mul为无符号乘,imul为有符号乘,被乘数(multiplicand)存放在 AL 或者 AX里,64位系统有4种情形

;8位乘法,溢出的位存放在 AH, AL为低8位,下面同理
AL * 8bit = AH AL

;下面分别为16 32 64位乘法
AX * 16bit = DX AX
EAX * 32bit = EDX EAX
RAX * 64bit = RDX RAX

div/idiv

DIV/IDIV  divisor

div为无符号乘,idiv为有符号乘,商(quotient)存放在 AX,余数(remainder)存放在 DX

AX/8bit = AL AH

DX AX/16bit = AX DX

EDX EAX/32bit = EAX EDX

RDX RAX/64bit = RAX RDX


cmp

比较两个数

CMP destination, source

jmp

JMP label

无条件跳转


有条件跳转

下面是有符号

JE/JZ        Jump Equal or Jump Zero     ZF
JNE/JNZ     Jump not Equal or Jump Not Zero     ZF
JG/JNLE     Jump Greater or Jump Not Less/Equal     OF, SF, ZF
JGE/JNL     Jump Greater/Equal or Jump Not Less     OF, SF
JL/JNGE     Jump Less or Jump Not Greater/Equal     OF, SF
JLE/JNG     Jump Less/Equal or Jump Not Greater     OF, SF, ZF

下面是无符号

JE/JZ        Jump Equal or Jump Zero         ZF
JNE/JNZ     Jump not Equal or Jump Not Zero ZF
JA/JNBE     Jump Above or Jump Not Below/Equal  CF, ZF
JAE/JNB     Jump Above/Equal or Jump Not Below  CF
JB/JNAE     Jump Below or Jump Not Above/Equal  CF
JBE/JNA     Jump Below/Equal or Jump Not Above  AF, CF

其他特殊跳转指令

JXCZ   Jump if CX is Zero  none
JC  Jump If Carry   CF
JNC Jump If No Carry    CF
JO  Jump If Overflow    OF
JNO Jump If No Overflow OF
JP/JPE  Jump Parity or Jump Parity Even PF
JNP/JPO Jump No Parity or Jump Parity Odd   PF
JS  Jump Sign (negative value)  SF
JNS Jump No Sign (positive value)   SF

loop

loop    label

循环指令,需要借助 ecx 寄存器,每次循环 ecx 减去1,当 ecx为0时跳出

逻辑指令

AND      AND     operand1, operand2
OR   OR      operand1, operand2
XOR  XOR     operand1, operand2
TEST     TEST    operand1, operand2
NOT  NOT     operand1

test指令跟and一样,只不过不改变源操作数

移位指令

shl        左移
shr        右移
sal        有符号左移
sar        有符号右移
rol        循环左移
ror        循环右移
rcl        带进位的循环左移
rcr        带进位的循环右移
shld       双精度左移
shrd       双精度右移

循环左移,左边移出的那一位将放在低位,循环右移右边移出的那一位放入高位


movsb/movsw/movsd/movsq

单位分别为1,2,4,8字节

移动 DS:RSI 数据到 ES:EDI,方向标志位0 ESI EDI每次增加,方向标志位 1,ESI EDI 每次减少

cld/std

cld 方向标志位置0,即DF=0,std 方向标志为置1,即DF=1

rep

rep - ECX > 0时重复

repz repe - ECX > 0 且 ZF == 1 时重复

repnz repne - ECX > 0 且 ZF == 0 时重复

每次重复,ecx都会减1

下面是复制10个字节的模拟

cld
mov esi,OFFSET string1
mov edi, OFFSET string2
mov ecx,10
rep movsb


call

call function_name

调用函数,主要做了如下2件事

1.将调用函数后需要执行的指令地址压入栈,即call后面的指令地址

2.改变 RIP 指向调用目标地址

ret

弹出返回地址,把控制权交还给调用者

push/pop

进栈出栈,RBP 为指向栈底的指针


cmpsb/cmpsw/cmpsd/cmpsq

比较 ESI 指向的内存操作数与 EDI指向的内存操作数,也可以使用重复前缀 rep

scasb/scasw/scasd/scasq

分别将 AL/AX/EAX/RAX中的值与 EDI 指向的 1,2,4,8字节进行比较,可以结合 repe使用

stosb/stosw/stosd/stosq

分别将AL/AX/EAX/RAX内容存入 EDI 中偏移量指向的内存,EDI 根据方向标志位递增或者递减

lodsb/lodsw/lodsd/lodsq

分别从 ESI 指向的内存地址加载1,2,4,8字节到 AL/AX/EAX/RAX,ESI 根据方向标志位递增或者递减


上一篇: nasm寻址模式
下一篇: nasm函数调用约定
作者邮箱: 203328517@qq.com