masm 匯編常用指令 (中)


注釋/說明

masm 匯編語言常用指令 (上) : https://www.cnblogs.com/ICeVe/p/14589519.html

L: 立即數

M: 內存變量

R: 寄存器

S: 標號

not

按位進行非運算, 操作數只有一個

not M/R

and

按位與運算

and M/R, L/M/R

or

按位或運算

or M/R, L/M/R

xor

按位異或運算

xor M/R, L/M/R

test 和 cmp

test 和 cmp 都是比較指令. 不過實現方式不同

test 是將兩個操作數進行 and 運算, 結果將由標志位寄存器 (如 pf, sf, zf 等) 來判斷. test 不會修改兩個操作數的值, 也不會讓其中一個操作數保存計算結果

cmp 是用目標操作數減去源操作數, 結果將由標志位寄存器 (如 pf, sf, zf 等) 來判斷. cmp 同樣不會修改兩個操作數的值, 也不會讓其中一個操作數保存計算結果

test M/R, L/M/R
cmp M/R, L/M/R

跳轉指令

無條件跳轉 : jmp

即直接跳轉, 沒有條件

jmp S

有條件跳轉

有條件跳轉比較繞, 因此判斷是否跳轉一定要看准標志位寄存器和比較指令, 比較指令決定標志寄存器的狀態, 既而決定跳轉結果

有符號數與無符號數

標志 指令 描述
of = 1 jo 如果溢出, 則跳轉
of = 0 jno 如果不溢出, 則跳轉
pf = 1 jp 如果奇偶校驗位置1, 則跳轉
pf = 0 jnp 如果奇偶校驗位置 0, 則跳轉
sf = 1 js 如果符號位置 1, 則跳轉
sf = 0 jns 如果符號位置 0, 則跳轉
zf = 1 je

jz
如果相等, 則跳轉

如果為 0, 則跳轉
zf = 0 jne

jnz
如果不想等, 則跳轉

如果不為 0, 則跳轉

有符號數

標志 指令 描述
sf != of jl

jnge
如果小於, 則跳轉

如果不大於等於, 則跳轉
sf = of jge

jnl
如果大於等於, 則跳轉

如果不小於, 則跳轉
zf = 1 or sf != of jle

jng
如果小於等於, 則跳轉

如果不大於, 則跳轉
zf = 0 and sf != of jg

jnle
如果大於, 則跳轉

如果不小於或不等於, 則跳轉

無符號數

標志 指令 描述
cf = 1 jb

jc

jnae
如果低於, 則跳轉

如果進位標志位置 1, 則跳轉

如果不高於或不等於, 則跳轉
cf = 0 jae

jnb

jnc
如果高於或等於, 則跳轉

如果不低於, 則跳轉

如果標志不置 1, 則跳轉
cf = 1 or zf = 1 jbe

jna
如果低於或等於, 則跳轉

如果不高於, 則跳轉
cf = 0 and zf = 0 ja

jnbe
如果高於, 則跳轉

如果不低於或不等於, 則跳轉

loop

即循環指令, ecx 作為計數器, 每執行一次 loop 指令, ecx 都會減 1, 當 ecx 為 0 時跳過 loop 指令, 繼續執行下一條指令

loop S

push

將內存變量或寄存器的值壓入棧中進行保存, 同時 esp - n. 其中 n 為壓棧的字節數

push L/M/R

pop

將壓入棧中的內存變量或寄存器的值彈出到指定的 寄存器/內存變量

pop M/R

call

call 可看作是一種跳轉指令, 執行 call 指令后會自動跳轉到操作數 (一般為標號) 所在的地址上. 同時還會將 call 下方的一條指令的地址壓入棧中, 以確保函數執行完畢后能正常運行.

call S

ret

棧頂的值彈出至 eip, 以便函數執行完畢后能正常運行. 該指令不需要操作數 (僅在 stdcall 調用約定下)

ret 

nop

空操作, 不做任何行為

nop

cld

方向標志 (df) 清零, 使程序在執行字符串操作時按從左到右的順序讀取字符 ( 即先從地址較低的位置上讀取 ). 該指令不需要操作數

cld

std

方向標志 (df) 置 1, 使程序在執行字符串操作時按從右到左的順序讀取字符 ( 即先從地址較搞的位置上讀取 ). 該指令不需要操作數

std

rep

性質和 loop 類似, 也是一種循環指令, ecx 作為 計數器, 當 ecx 為 0 時 rep 結束指令. 常和字符串指令配合使用. rep 后面跟字符串指令.

每執行一次指令, edi / esi 會 + 4

rep opreate

repz / repe

與 rep 相同, 不過需要對標志位寄存器 zf 作判斷. 如果 zf 或 ecx 為 0 時 結束指令. 常和字符串指令配合使用. repz / repe 后面跟字符串指令

每執行一次指令, edi 或 esi 會 + 4

repz opreate
repe opreate

repnz / repne

與 repz / repe 相同, 如果 zf 置 1 或 ecx 為 0 時 結束指令. 常和字符串指令配合使用. repz / repne 后面跟字符串指令

每執行一次指令, edi 或 esi 會 + 4

repnz opreate
repne opreate

movs

和 mov 類似, 不過它專門用來將字符從一個地方復制到另一個地方. movs 通常有后綴 (如 b, 字節; w, 字; d, 雙字; q, 四字), 用來表示每次復制字符的字節大小. movs 默認由 esi 作為源操作數, edi 為目標操作數, 因此不需要寫操作數. esi 和 edi 一般獲取的都是字符串的首或字符的地址

movsb
movsw
movsd
movsq

cmps

字符比較指令, 與 cmp 類似, 用目標操作時減去源操作數的字符來判斷, 如果在執行 cmps 時若兩個字符串中發現字符不同時則結束指令. 由於每次只能比較一個字符, 因此通常和 repnz / repne 配合使用. 默認由 esi 作為源操作數, edi 為目標操作數, 因此不需要寫操作數.

cmps 可以像 movs 一樣添加后綴 ( 如 b, 字節; w, 字; d, 雙字; q, 四字 )

cmpsb
cmpsw
cmpsd
cmpsq

scas

scas 的作用與 cmps 差不多, 不同的是 scas 在執行 scas 時若兩個字符串中發現字符相同時則結束指令. 由於每次只能比較一個字符, 因此通常和 repnz / repne 配合使用. 默認由 esi 作為源操作數, edi 為目標操作數, 因此不需要寫操作數.

scasb
scasw
scasd
scasq

stos

用來將 eax 中的值復制到由 edi 所表示的內存地址上. 可以與 rep 配合起來用, 實現多個位置的初始化. stos 可以添加后綴 ( 如 b, 字節; w, 字; d, 雙字; q, 四字 ) . 默認由 edi 操作數, 因此不需要寫操作數.

stosb
stosw
stosd
Stosq

lods

與 stos 相反, 將 esi 所表示的內存地址上的值復制到 eax 中, 不需要與 rep 配合起來用, 因為這樣會使 eax 頻繁遭到復寫. lods 可以添加后綴 ( 如 b, 字節; w, 字; d, 雙字; q, 四字 ) . 默認由 esi 操作數, 因此不需要寫操作數.

lodsb
lodsw
lodsd
lodsq


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM