Skip to content

Assembly x86-64 Instructions API

核心 x86-64 指令,涵盖数据传送、算术、控制流和 Linux 系统调用(Intel/NASM 语法)。

1 class · 8 methods

Instructions

8 methods

基本的 x86-64 整数指令。大小为 8/16/32/64 位(byte/word/dword/qword);助记符遵循 Intel 语法(dst, src)。

mov dst, src

将 src 复制到 dst。操作数大小必须匹配;不允许内存到内存的传送。

Parameters

NameTypeDescription
dstreg | mem目标寄存器或内存位置。
srcreg | mem | imm源寄存器、内存或立即数。

Returns

Sets dst = src. Does not modify flags.

Example

assembly
mov rax, 42              ; imm -> reg
mov rbx, rax             ; reg -> reg
mov qword [rsp-8], 7     ; imm -> mem
mov rcx, [rsp-8]         ; mem -> reg
; mov [a], [b]            ; INVALID — use a register in between
add dst, src / sub dst, src

将 src 加到(或从)dst 中,结果存入 dst 并更新标志位。

Parameters

NameTypeDescription
dstreg | mem目标操作数;也接收结果。
srcreg | mem | imm源操作数(dst 为内存时不能是内存)。

Returns

dst = dst +/- src. Sets CF, OF, SF, ZF, AF, PF.

Example

assembly
add rax, rbx     ; rax += rbx
sub rsp, 32      ; allocate 32 bytes of stack
add [counter], 1 ; increment a memory counter
; signed overflow check:
add rax, rbx
jo .overflow     ; jump if OF=1 (signed overflow)
imul dst, src[, imm] (two/three-operand form)

有符号乘法。双操作数:dst = dst * src(低 64 位)。三操作数:dst = src * imm。单操作数形式在 rdx:rax 中返回 128 位结果。

Parameters

NameTypeDescription
dstreg目标寄存器(双/三操作数形式必须是寄存器)。
srcreg | mem乘数。
immimm (optional)立即数乘数(三操作数形式)。

Returns

dst = dst * src (or src * imm). Sets CF and OF if the result overflowed the low half.

Example

assembly
imul rax, rbx        ; rax = rax * rbx
imul rcx, 10         ; rcx = rcx * 10
imul r8, r9, 5       ; r8 = r9 * 5
; full 128-bit signed:
mov rax, 1234567890
imul rbx             ; rdx:rax = rax * rbx
cmp a, b / test a, b

cmp 计算 a-b 并设置标志位;test 计算 a&b 并设置标志位。两者都不修改操作数 —— 它们为 jcc 设置标志位。

Parameters

NameTypeDescription
areg | mem第一个操作数。
breg | mem | imm第二个操作数。

Returns

Sets ZF, SF, CF, OF, AF, PF per the result. Operands unchanged.

Example

assembly
cmp rax, rbx
je  .equal        ; jump if rax == rbx
jl  .less         ; signed: rax < rbx
jb  .below        ; unsigned: rax < rbx

test rax, rax
jz  .is_zero      ; rax == 0
js  .is_neg       ; rax < 0 (high bit set)
test rcx, 0x1
jnz .odd          ; rcx is odd
jmp label / jcc label

无条件(jmp)或条件(jcc)跳转到标签或地址。条件跳转测试 cmp/test/算术设置的标志位。

Parameters

NameTypeDescription
labellabel | reg | mem跳转目标(直接标签,或通过寄存器/内存间接跳转)。

Returns

Transfers control to label. No register/flag changes (jcc may consume flags).

Example

assembly
; signed comparisons:
cmp rax, rbx
je  .eq      ; equal              (ZF=1)
jne .ne      ; not equal          (ZF=0)
jl  .lt      ; less than          (SF!=OF)
jge .ge      ; greater or equal   (SF==OF)
; unsigned:
jb  .below   ; below              (CF=1)
ja  .above   ; above              (CF=0 and ZF=0)
; indirect jump (jump table):
jmp rdi      ; jump to address in rdi
push src / pop dst

push 将 rsp 减 8(64 位模式)并将 src 存入 [rsp];pop 将 [rsp] 加载到 dst 并将 rsp 加 8。

Parameters

NameTypeDescription
src/dstreg | mem | imm (push only)要压入的值或 pop 的目标。

Returns

push: rsp -= 8, [rsp] = src. pop: dst = [rsp], rsp += 8. Flags unchanged.

Example

assembly
push rax           ; save rax
push qword 42      ; push an immediate
pop  rbx           ; rbx = top of stack

; save/restore callee-saved registers
push rbx
push r12
; ... function body ...
pop  r12
pop  rbx
ret
call label / ret

call 将返回地址(8 字节)压栈并跳转到 label。ret 将返回地址弹回 rip,将控制权返回调用者。

Parameters

NameTypeDescription
labellabel | reg | mem函数入口点。

Returns

call: rsp -= 8, [rsp] = return addr, rip = label. ret: rip = [rsp], rsp += 8.

Example

assembly
; set up args (System V AMD64): rdi, rsi, rdx, ...
mov rdi, 1
mov rsi, 2
call add_two       ; rax = add_two(1, 2)

add_two:
    mov rax, rdi
    add rax, rsi
    ret            ; return to caller, rax holds result

; tail call: jmp instead of call+ret
jmp other_func     ; other_func returns directly to OUR caller
syscall (Linux x86-64)

进入内核执行系统调用。系统调用号放在 rax 中;最多六个参数在 rdi、rsi、rdx、r10、r8、r9 中。返回值在 rax;会破坏 rcx 和 r11。

Parameters

NameTypeDescription
raxreg系统调用号(write=1,read=0,exit=60,mmap=9)。
rdi..r9reg最多 6 个参数(注意:第 4 个参数是 r10 而非 rcx)。

Returns

Result in rax (negative value indicates -errno). rcx and r11 are clobbered.

Example

assembly
; write(1, msg, 12)
mov rax, 1          ; write
mov rdi, 1          ; fd = stdout
lea rsi, [rel msg]
mov rdx, 12
syscall             ; rax = bytes written

; exit(0)
mov rax, 60
xor rdi, rdi
syscall             ; never returns