四.汇编语法

1.AT&T汇编语法

前面写过,boot.s程序使用的是as86汇编语法,而进入head.s需要启动linux的时候,就需要使用AT&T汇编语法了,这与intel的汇编语法不一样,微软使用的是intel的汇编语法,暂时就不去了解了。我们目前使用的GNU工具,使用的是AT&T汇编语法,所以AT&T汇编语法是可以简单的学习一下的。

2.开始汇编代码编写测试

2.1 第一个测试程序

这部分主要是参考网络上的一些文章,从这些文章中快速了解at&t汇编语法在机器上实现的效果。

首先,编写demo.s汇编程序,代码如下所示:

.section .data
.section .text
.globl _start
_start:
movl $1, %eax
movl $4, %ebx
int $0x80

编译程序,如下所示:

$ as demo.s -o demo.o
$ ld demo.o -o demo
$ ./demo
$ echo $?
4

我们需要查询一下int 0x80的调用规则,才能更近一步了解程序的含义。

我截取一部分图,如下图所示:


linux系统调用

所以,只要eax=1,我们就能调用到sys_exit函数。而ebx则是sys_exit函数的返回值。

2.2 汇编语法

2.2.1 基本语法

内存寻址在指令中可以表示成如下的通用格式:

ADDRESS_OR_OFFSET(%BASE_OR_OFFSET,%INDEX,MULTIPLIER)

它所表示的地址可以这样计算出来:

目标地址 = ADDRESS_OR_OFFSET + BASE_OR_OFFSET + MULTIPLIER * INDEX

其中ADDRESS_OR_OFFSET和MULTIPLIER必须是常数,BASE_OR_OFFSET和INDEX必须是寄存器。在有些寻址方式中会省略这4项中的某些项,相当于这些项是0。

1.直接寻址

根据以上公式,只使用ADDRESS_OR_OFFSET寻址,例如movl ADDRESS, %eax把ADDRESS地址处的32位数传送到eax寄存器。

2.变址寻址

movl data_items(,%edi,4), %eax就属于这种方式,用于访问数组很方便。

3.间接寻址

只使用BASE_OR_OFFSET寻址,例如movl (%eax), %ebx,把eax寄存器的值看作地址,把这个地址处的32位数传送到ebx寄存器。

4.基址寻址

只使用ADDRESS_OR_OFFSET和BASE_OR_OFFSET寻址,例如movl 4(%eax), %ebx,用于访问结构体成员比较方便,例如一个结构体的基地址保存在eax寄存器中,其中一个成员在结构体内偏移量是4字节,要把这个成员读上来就可以用这条指令。

5.立即数寻址

就是指令中有一个操作数是立即数,例:movl $3, %eax。

6.寄存器寻址

就是指令中有一个操作数是寄存器。在汇编程序中寄存器用助记符来表示,在机器指令中则要用几个Bit表示寄存器的编号,这几个Bit与可以看做寄存器的地址,但是和内存地址不在一个地址空间。

我从网上摘抄一个整体的描述表格:


AT&T汇编语法和intel汇编语法对比

2.2.2 asm volatile GCC的内嵌汇编语法

我们分为两种,一种是基本的内联汇编语法,一种是带有c/c++表达式的内联汇编语法。

1.基本的内联汇编语法

格式为:

__asm__ __volatile__("Instruction List");

2.带有c/c++格式的内联汇编语法

格式为:

__asm__ __volatile__("Instruction List" : Output : Input : Clobber/Modify);

3 中断功能

3.16 INT 10H

1.AH=00H 设定显示模式的服务程序,AL 寄存器表示欲设定的模式

AL 文字/图形 分辨率 颜色
00 文字 40*25 2
01 文字 40*25 16
02 文字 80*25 2
03 文字 80*25 16
04 图形 320*200 2
05 图形 320*200 4
06 图形 640*200 2

2.AH=01H

光标起始处与终止处分别由 CL 与 CH 的 0 到 4 位表示。
CH 的第 7 位必须是 0,第 5、6 位表示光标属性

位 6 位 5 属性
0 0 正常
0 1 隐形
1 0 N/A
1 1 闪烁缓慢

3.AH=02H

此功能是设定光标位置,位置用 DH、DL 表示,DH 表示列号,DL 表示行号。由左至右称之为『列』,屏幕最上面一列为第零列,紧靠第零列的下一列称为第一列……;由上而下称之为『行』,屏幕最左边一行称之为第零行,紧靠第零行右边的一行为第一行。故最左边,最上面的位置为 DH=0 且 DL=0;最左边第二列,DH=1,DL=0。如果是文字模式时,BH 为欲改变光标位置的显示页,如果是图形模式,BH 要设为 0。
以行列来说明 DH、DL 之意义,底下以坐标方式解释。在文字模式下,字符的位置类似数学直角座标系的座标,但是 Y 轴方向相反,Y 轴是以屏幕最上面为零,越下面越大,直到 24 为止,存于 DH 内。X 轴和直角座标系相同,越右边越大,存于 DL 内,其最大值视显示模式而变。

4.AH=03H

这个中断服务程序返回时,会在 DX 里面有光标的行列位置,CX 内有光标的大小,DX、CX 之数值所代表的意义和 AH=01H/INT 10H、AH=02H/INT 10H 相同。

5.AH=13H

参数 说明
AL 显示模式
BH 视频页
BL 属性值(如果AL=0x00或0x01)
CX 字符串的长度
DH,DL 屏幕上显示起始位置的行、列值
ES:BP 字符串的段:偏移地址

显示模式分如下几种:

参数 说明
AL=0x00 字符串只包含字符码,显示之后不更新光标位置,属性值在BL中
AL=0x01 字符串只包含字符码,显示之后更新光标位置,属性值在BL中
AL=0x02 字符串包含字符码及属性值,显示之后不更新光标位置
AL=0x03 字符串包含字符码及属性值,显示之后更新光标位置

3.19 INT 13H

1.AH=00H 软、硬盘控制器复位

功能说明:
此功能复位磁盘(软盘和硬盘)控制器板和磁盘驱动器,它在磁盘控制器芯片上完成复位操场作并在磁盘进行所需的操作之前做一系列用于磁盘校准磁盘操作。
当磁盘I/O功能调用出现错误时,需要调用此功能,此刻复位功能将使BIOS象该磁盘重新插入一样检查驱动器中磁盘状态,并将磁头校准使之在应该在的位置上。
此功能调用不影响软盘或硬盘上的数据。

参数1 入口参数2 说明
AH=00H DL需要复位的驱动器号 若产生错误,进位标志CF=1,错误码在AH寄存器。详情请见磁盘错误状态返回码一文。

2.AH=02H 读扇区

调用此功能将从磁盘上把一个或更多的扇区内容读进存贮器。因为这是一个低级功能,在一个操作中读取的全部扇区必须在同一条磁道上(磁头号和磁道号相同)。BIOS不能自动地从一条磁道末尾切换到另一条磁道开始,因此用户必须 把跨多条磁道的读操作分为若干条单磁道读操作。

参数 说明
AL 置要读的扇区数目,不允许使用读磁道末端以外的数值,也不允许使该寄存器为0
DL 需要进行读操作的驱动器号
DH 所读磁盘的磁头号
CH 磁道号的低8位数
CL 低5位放入所读起始扇区号,位7-6表示磁道号的高2位
ES:BX 读出数据的缓冲区地址

返回参数:
如果CF=1,AX中存放出错状态。读出后的数据在ES:BX区域依次排列。
详情请参见磁盘错误状态返回码一文。

3.AH=03H 写扇区

功能说明:
调用此功能将从磁盘上把一个或更多的扇区内容写入驱动器。因为这是一个低级功能,在一个写入操作中的全部扇区必须在同一条磁道上(磁头号和磁道号相同)。BIOS不能自动地从一条磁道末尾切换到另一条磁道开始,因此用户必须把跨多条磁道的写操作分为若干条单磁道写操作。

参数 说明
AL 置要写的扇区数目,不允许使用读磁道末端以外的数值,也不允许使该寄存器为0
DL 需要进行写操作的驱动器号
DH 所写磁盘的磁头号
CH 磁道号的低8位数
CL 低5位放入所读起始扇区号,位7-6表示磁道号的高2位
ES:BX 放置写入数据的存储区地址

返回参数:
如果CF=1,AX中存放出错状态。
详情请参见磁盘错误状态返回码一文。

4.AH=08H 得到磁盘驱动器参数

参数 说明
AX 0
BH 0
BL 1=360K 5.25寸,2=1.2M 5.25寸 ,3=720K 3.5寸 ,4=1.44M 3.5寸
CH 存放10位磁道数的低8位(高2位在CL的D7、D6中)。1表示有1个磁道,2表示有2个磁道,依次类推。
CL 0~5位存放每磁道的扇区数目。6和7位表示10位磁道数的高2位。
DH 最大磁头号(或说磁面数目)。0表示有1个磁面,1表示有2个磁面
DL 本机软盘驱动器的数目
ES:SI 指向软盘参数表

错误信息:
若产生错误,进位标志CF=1,AH存放错误信息码。

把以上得到的磁盘参数分别放到parameters处相应的位置,磁盘参数占11字节的空间。 由于si是1个字节,所以是ax,bx,cx,dx,es,si共2*6-1=11字节空间。

3.21 INT 15H

1.AH=88H 获取扩展内存大小

返回:

参数 说明
AX 内存大小,获取1MB存储区以上的内存大小
CF 标志位,0表示没有错误

磁盘错误状态:

AH 说明
00H 未出错
01H 非法功能调用命令区。
02H 地址标记损坏,扇区标识(ID)无效或未找到。
03H 企图对有写保护的软盘执行写操作。
04H 所寻找的扇区没找到。
05H 复位操作失败。
06H 无介质。
07H 初始化错误,数据未存在DMA的64K缓冲区内。
08H DMA故障
09H DMA边界错误,数据未存在DMA的64K缓冲区内。
0AH 检测出错误码率的扇区标志。
0BH 所寻找的磁道没找到。
0CH 介质类型没发现。
0DH 扇区号有问题。
0EH 发现控制数据地址标记。
0FH 超出DMA边界
10H 读磁盘时奇偶校验错,且纠错码(EDC)不能纠正。
11H 读磁盘时奇偶校验错,但纠错码(EDC)已纠正错误。
20H 控制器错。
40H 查找操作无效。
80H 超时错误,驱动器不响应。
AAH 驱动器未准备好。
BBH 不明错误。
CCH 被选驱动器出现写故障。
E0H 错误寄存器是零
FFH 非法操作。

4 保护模式以及编程

4.1 内存管理寄存器

从网上抄录一幅图:


内存管理寄存器

从这幅图中,我们可以看出,内存管理器分为全局描述符表寄存器GDTR、中断描述符表寄存器IDTR、TR任务寄存器、局部描述符表寄存器LDTR。

  1. GDTR

GDTR寄存器用于存放全局符号描述表(GDT)的线性基地址(32位)和表长度值(16位)。基地址指定GDT表中的字节0在线性地址空间中的地址,表长度指明GDT表的字节长度值,指令LGDT和SGDT分别用于加载和保存GDTR寄存器的内容。在机器刚上电或处理器复位后,基地址被默认设置为0,而表长度被设置成0xFFFF。在保护模式初始化过程中必须给GDTR加载一个新值。

上面所说的就是GDTR寄存器。我们需要注意,是寄存器。而下面要说的是全局描述符表,是64位的。我们只需要放到内存中即可。然后将内存地址给GDTR寄存器。就可以访问表中的内容了。

GDTR具体描述

相应的描述如下:
G:
G=0时,段限长的20位为实际段限长,最大限长为220=1MB。
G=1时,则实际段限长为20位段限长乘以212=4KB,最大限长达到4GB。

D/B:
D位:
当描述符指向的是可执行代码段时,则会形成D位,D=1使用32位地址和32/8位操作数,D=0使用16位地址和16/8位操作数。

B位:
当指向的是向下扩展的数据段,这一位就叫做B位,B=1时段的上界为4GB,B=0时段的上界为64KB。
当指向的是堆栈段,这一位也叫做B位,B=1使用32位操作数,堆栈指针用ESP,B=0时使用16位操作数,堆栈指针用SP。

P:
表示段是否存在于内存中,P为1表示存在。
该位在未开启分页模式的情况下有用。如果内存不足可以把内存中的某些段暂时移动到硬盘上去,腾出空间。这样如果在访问段时CPU发现P为0,就会触发异常。操作系统捕获到异常后会把段从硬盘挪会内存去,然后把P置为1。

如果开启了分页模式,那么分页模式本身就支持内存置换。就不需要这个P字段了。

DPL:
该位为特权级,0为最高特权级,3为最低,表示访问该段时CPU所需处于的最低特权级。

TYPE:
当TYPE<=7时,表示的是数据段。

说明
0 只读
1 只读,已访问
2 读写
3 读写,已访问
4 只读,向下扩展
5 只读,向下扩展,已访问
6 读写,向下扩展
7 读写,向下扩展,已访问

当TYPE>=8时,表示的是代码段。

说明
8 只执行
9 只执行,已访问
10 执行,可读
11 执行,可读,已访问
12 只执行,一致
13 只执行,一致,已访问
14 执行,可读,一致
15 执行,可读,一致,已访问
  1. IDTR

与GDTR的作用类似,IDTR寄存器用于存放中断描述符表的32位线性基地址和16位表长度值。指令LIDT与SIDT分别用于加载和保存中断描述符表的内容。在机器刚刚上电或处理器复位后,基地址默认设置为0,长度值被设置为0xFFFF

  1. TR

TR寄存器用于存放当前任务TSS段的16位段选择符,32位基地址、和16位段长度和描述符属性值。它引用GDT表中的一个TSS类型放入描述符,指令LTR和STR分别用于加载和保存TR寄存器的段选择符部分。

  1. LDTR

LDTR用于存放局部描述符表LDT的32位线性基地址、16位段限长和描述符属性值。指令LLDT和SLDT用于加载和保存LDTR寄存器的段描述符部分,包含LDT表的段必须在GDT表中有一个段描述符项。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 159,015评论 4 362
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,262评论 1 292
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 108,727评论 0 243
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 43,986评论 0 205
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,363评论 3 287
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,610评论 1 219
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,871评论 2 312
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,582评论 0 198
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,297评论 1 242
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,551评论 2 246
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,053评论 1 260
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,385评论 2 253
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,035评论 3 236
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,079评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,841评论 0 195
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,648评论 2 274
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,550评论 2 270

推荐阅读更多精彩内容