汇编
ddatsh
汇编语言主要是 Intel 格式和 AT&T 格式。最常用的是 Intel 格式
Windows 平台 Intel 格式最常用的是两种汇编格式:MASM 和 NASM
《x86汇编语言-从实模式到保护模式》教你如何直接控制硬件,不借助于 BIOS、DOS、Windows、Linux 或者任何其他软件支持的情况下来显示字符、读取硬盘数据、控制其他硬件等
王爽的《汇编语言》基于 MASM,不少内容也过于陈旧,只能作为参考了
nasm 官网 nasm.us
寄存器
寄存器 | 宽度 | 类型 |
---|---|---|
rax | 64bit | long |
eax | 32bit | int |
ax | 16bit | short |
ah | 8bit | ax 寄存器的高八位 |
al | 8bit | al 寄存器的低八位 |
“X” 表示 Extern,表示从 8 位扩展到 16 位
“E”,还是 Extern 的意思
64 位 , “E” 换成 “R”,如RAX
通用寄存器
数据寄存器 | 解释 | 备注 |
---|---|---|
EAX(Accumulator) | 累加器 | 乘除法中被自动使用;Win32 一般用在函数的返回值 |
EBX(Base) | 基址寄存器 | DS 段中的数据指针 |
ECX(Count) | 计数器 | 循环(LOOP)或串操作中,ECX 用来进行循环计数,每执行一次循环,ECX 都会被 CPU 自动减一;c++中保存 this |
EDX(Data) | 数据寄存器 |
指针变址寄存器 | 解释 | 备注 |
---|---|---|
EBP(Base Pointer) | 扩展基址指针寄存器 | SS 段中堆栈内数据指针。EBP 由高级语言用来引用参数和局部变量,通常称为堆栈基址指针寄存器 |
ESP(Stack Pointer) | 堆栈指针寄存器 | 表示栈顶指针, 指向栈顶地址 与 SS 相配合使用 |
ESI(Source Index) | 源变址寄存器 | 默认段地址和 DI 一样, 在 DS 中和 DS 联用 |
EDI(Destination Index) | 目的指针寄存器 | 一般情况下与 ds 联用, 来确定某个储存单元的地址 |
sp 和 bp 段地址默认在 SS 中
sp 指向栈顶元素地址,有自加和自减能力, bp 没, 但可以定位栈中某个元素的物理地址
变址寄存器DI/SI可以和 bx/bp 联用, 和 bx 连用时, 段地址在 DS 中, 和 bp 联用时, 段地址在 SS 中. 也可以单独使用, 单独使用时, 段地址默认在 DS 中, 想要越段使用, 加上段前缀即可
串指令操作中,si 和 ds 联用, 确定目标源地址,di 和 es(附加段寄存器) 联用, 确定传送的目的地址. 说白了就是, 分别寻址数据段和附加段. 在串指令中,si 和 di 具有自加和自减功能
段寄存器
寄存器 | 解释 备注 |
---|---|
CS(Code Segment) | 代码段 |
DS(Data Segment) | 数据段 |
SS(StackSegment) | 堆栈段 |
ES(Extra Segment) | 附加数据段 |
FS | 附加数据段 |
GS | 附加数据段 |
标志寄存器
CPU 根据指令的执行结果,自己操作这个寄存器
nasm伪指令
初始化数据:db 家族
数据类型 | 大小 | 伪指令 | 含义 |
---|---|---|---|
byte | 8 | 位 | db define byte |
word | 16 | 位 | dw define word |
dword | 32 | 位 | dd define doubleword |
qword | 64 | 位 | dq define quadword |
tword | 80 | 位 | dt define tword |
oword | 128 | 位 | do define oword |
yword | 256 | 位 | dy define yword |
非初始化数据:resb 家族
resb 相当于 Microsoft MASM 语法中的 db ?
伪指令 | 含义 |
---|---|
resb | reserve byte |
resw | reserve word |
resd | reserve doubword |
resq | reserve quadword |
rest | reserve tword |
reso | reserve oword |
resy | reserve yword |
包含 binary 文件
incbin "file.dat" ; include the whole file
incbin "file.dat",1024 ; skip the first 1024 bytes
incbin "file.dat",1024,512 ; skip the first 1024, and
; actually include at most 512
$
标号和 times 重复
$ 标号表示 nasm 编译后当前指令位置
$$ 标号表示当前 section 起始位置
times 510-($-$$) db 0
dw 0xaa55
;经常出现在 boot 磁盘 MBR 引导代码中,除了最后 2 个字节和 code 代码外的区域全部写 0 值
hello.asm
section .data
msg:
db "hello, world", 10
len equ $-msg
section .text
global main
main:
mov edx, len
mov ecx, msg
mov ebx, 1
;直接使用sys_write系统调用
mov eax, 4
int 0x80
mov ebx, 0
mov eax, 1
int 0x80
nasm -felf32 hello.asm && ld -melf_i386 -e main -o hello hello.o