! ;
注释符号
. 后面 跟随的标记都是汇编指示符 伪指令 伪操作符
编译时不产生任何代码
汇编指示符 = 伪操作码 + 0/多个操作数
例如:
.global begtext ,begdata ,begbass
其中.global
是伪操作码
begtext
等 是伪操作数,此处也是标号
引用标号时无需 :冒号 begtext
不同的编译器支持不同的伪操作符
.global
定义随后的标号 标识符 都是全局的或者外部的 他们供ld86使用
.text
定义正文段
.data
定义数据段
.bbs
定义未初始化数据段
直接赋值的宏定义:
BOOTSEG=0x07c0
保留关键字:
如:entry
entry + 标号 用于告知ld86在链接时将标号包括进来
立即数寻址 或者使用符号
直接内存引用寻址
间接内存引用寻址
寄存器寻址
间接内存引用
disp(base,index,scale)
访问
(base + index * scale ) + disp
的地址
(%eax)
访问 以 eax中的数据 作为地址 <===> (base)
4(%eax)
访问 以eax中的数据+4 作为地址 <===> disp(base)
(%ebx,%eax,4)
访问 ebx上的值 + eax上的值*4 作为地址 <===> (base + index * scale )
(其中scale必须是1,2,4,8其中一个)
相当于C语言中的数组访问。要访问元素大小为4字节(例如int)的数组中第%eax个元素,起始地址为%eax上的值
x86 指令集
通用指令
与intel汇编不同 指令需要在最后加上代表所传输数据大小的后缀:b,w,l 分表代表8位 16位 32位
数据传输指令
move
格式:mov 源 ,目的
形式:
mov 立即数,寄存器
mov 寄存器,寄存器
mov 内存,寄存器
mov 立即数,内存
mov 寄存器,内存
mov 内存,内存
push pop
操作的是esp寄存器 栈顶指针
push 立即数
push 寄存器
lea
将地址加载到寄存器
lea = load effective address
lea 内存,寄存器
movl 4(%ebx) , %eax 将ebx寄存器上的值+4 作为访问地址 访问到的内容存到eax寄存器中
leal 4(%ebx) , %eax 将ebx寄存器上的值+4 这个内存地址 存到eax寄存器中
movsx和movzx
movsx和movzx是将数据从位宽较小的变量扩展为位宽较大的变量的指令
实际使用movsx指令和movzx指令时,必须同时指定传输源和传输目标的大小,所以助记符后缀使用2个字符。请使用2个字符的后缀来替换movsx和movzx中的x
两种扩展方式:
无符号数使用 无符号扩展 也就是用零扩展
有符号数使用 有符号扩展
movsbl %al , %eax #将al寄存器中的8位有符号数扩展到32位并加载到eax寄存器
movswl %ax , %eax #将ax寄存器中的16位有符号数扩展到32位并加载到eax寄存器
movzbl %al , %eax #将al寄存器中的8位无符号数扩展到32位并加载到eax寄存器
movzwl %ax , %eax #将ax寄存器中的16位有符号数扩展到32位并加载到eax寄存器