上篇中,我们提到的语法都是基于Intel的汇编语法。
与之对应的是AT&T汇编,也是Linux内核中的汇编语法。
我们先学习intel汇编,主要是Intel的汇编和大学里面的教程一致,更加顺手。
先来复习下几个概念,然后会增加例子来进行实践
第一步部分中只是个引子,这部分中进行术语的描述。
寄存器,是位于处理器中的小存储。处理器可以从内存获取数据,但是很慢,所以需要内部存储数据的存储即寄存器。有16个通用的寄存器:
rax, rbx, rcx, rdx, rbp, rsp, rsi, rdi, r8, r9, r10, r11, r12, r13, r14, r15.
栈:因为处理只有非常有限数量的寄存器,所以栈是处理器通过特殊寄存器进行寻址的连续区域。
段: data数据段用于声明初始化数据或常量
bss用于声明非初始化变量
text用于代码。
先来看下整型数,基础数据类型是:byte,word,doubleword,quadword和double quadword.
一个byte是8位,一个word是2个byte,一个doubleword是4个bytes, 一个quadword是8个字节,一个double quadword是16个字节。
整型分为有符号和无符号的。例如,8位的无符号范围是0-255,有符号的事-128到127。
例如如下:
section .data
num1: equ 10
num2: equ 5
msg: db "Num is correct", 10
这里定义里3个常量num1,num2,msg。这里的db是NASM的伪指令。
常用的伪指令有: DB, DW, DD, DQ, DT, DO, DY,DZ,用于声明初始化数据。
RESB, RESW, RESD, RESQ, REST, RESO, RESY and RESZ用于声明费初始化变量。
INCBIN包含外部二进制文件
EQU定义常量。
TIMES反复执行数据指令。
ADD 整数加
SUB 减法
MUL 无符号乘
IMUL 符号乘
DIV 无符号除
IDIV 符号除
INC 增加
DEC 减法
NEG 取反
例如if,while,for
汇编中有cmp指令。
对比两个值,后面会接调整指令如下:
JE 相等跳转
JZ 等于0调整
JNE 不相等跳转
JNZ 不等于0调整
JG 第一个值大于第二个值
JGE 第一个值大于等于第二个值
JA 类似JG,但是对比无符号对比。
JAE 类似JGE,但是对比无符号对比。
section .data
num1: equ 100
num2: equ 50
msg: db "Sum is correct\n"
section .text
global _start
;; entry point
_start:
mov rax, num1
mov rbx, num2
add rax, rbx
cmp rax, 150
jne .exit
jmp .right
; Print message that sum is correct
.right:
mov rax, 1
mov rdi, 1
mov rsi, msg
mov rdx, 15
syscall
jmp .exit
.exit:
mov rax, 60
mov rdi, 0
syscall
编译连接运行
nasm -f elf64 -o addsum.o addsum.asm
ld -o addsum addsum.o
然后可以执行./addsum
本片完。