第二遍:汇编语言基础:寄存器和系统调用

寄存器

寄存器是处理器临时保存数据指令的的一部分。在x86_64架构中,寄存器能处理高达64位的数据。这意味着每个寄存器都可以保存该值
没符号整数:0〜18,446,744,073,709,551,616
有符号整数:-9,223,372,036,854,775,808 - 9,223,372,036,854,775,807

这是x86_64架构下的所有寄存器的逻辑图表。


屏幕快照 2019-08-20 下午7.25.00.png

这是我们的寄存器列表,表中有有四列:

  • 64位寄存器的列;
  • 32位寄存器
  • 16位寄存器
  • 8位寄存器:

各个寄存器的关系

这里是rax寄存器的图,你可以看到我们的一个64位寄存器叫做rax,还有eax 32位寄存器,那实际上不是它自己的寄存器,它是rax寄存器的一半,那么ax是16位寄存器是eax寄存器的一半。同理al寄存器是ax寄存器的一半。使用al寄存器就好像是一个8位寄存器,但它是 实际上修改了ax寄存器的低8位。以上说的并不需要刻意记忆,因为本文的立足点是让你能够读懂别人或C/C++编译器转译的汇编代码,你不记得的话,可以收藏本文已被你翻查。


不同数据长度的寄存器之间的关系

系统调用(Syscall)

系统调用是指程序向系统内核请求服务,系统调用因操作系统的不同而不同,因为不同的操作系统使用不同的内核。

  • 所有系统调用都有一个与之关联的ID(一个数字)
  • 系统调用的输入接受一个参数列表。


    寄存器参数顺序表

这是一个非常重要的表,当你使用系统调用时,它有许多输入是基于存储在寄存器中的值,并且是讲求顺序的,如果你想使用系统调用,你可以将对应系统调用的ID加载到rax寄存器中 并按上表指定的顺序加载参数在你的RAX寄存器中,如果你在这里还没有概念的话,可以跳过,往下看完一个示例,回头看就明白了

  • 第一个参数是rdi寄存器,
  • 第二个参数是rsi寄存器,
  • 第三个参数是rdx寄存器
  • 第四个参数是r10寄存器
  • 第五个参数是r8寄存器
  • 第六个参数是r9寄存器.

系统调用列表

我们这里只列出常用系统调用的ID,完整的系统调用ID列表,可以在网上都可以找得到。
系统调用ID示例表
  1. 正如你所见,文件操作的系统调用是和Unix/Linux交互的常用接口.ID列对应的数字和对应syscall列对应系统调用名称相关联。
  2. 与系统调用相关的还有参数,我这里用颜色标记了,和'#'相关这表明是直接来自寄存器的一个数字,用'$'符号和绿色标记的也是来自寄存器,但它不是真实的值,而是寄存器里面缓存的内存地址所指向的位置保存的值(如果你有C指针的基础,这就很容易理解了)。

sys_write系统调用示例引入

前文写到Hello World程序将"Hello World"字符串打印到屏幕,已经用到了sys_write系统调用,我们作为示例来讲解一下寄存器和系统调用之间是如何交互的。


sys_write参数类型
  • 第一个参数是文件描述符0代表文件输入,1代表文件输出,2代表文件错误。如果你只是将文本写到屏幕,那么就使用标准输出即可
  • 第二个文件描述符是缓存,即字符串输出到屏幕之前,首先写入的是高速缓存的位置
  • 第三个参数是字符串的长度

看完上面参数表,再回顾一下上面的寄存器ID参数表,看如何使用寄存器ID参数和下表的参数相关联,其实很简单,只需要将那些寄存器的值替换下表的参数列名即可。


屏幕快照 2019-08-20 下午9.58.43.png

所以,正如你所见

  • rax寄存器应该处理值1(也即是sys_write系统调用的ID),
  • rdi寄存器应该处理我们的文件描述符,
  • rsi寄存器应该处理字符串的缓存对象,
  • rdx寄存器应该处理字符串的长度.

最后,按照《参数类型表》的描述替换为各列寄存器对应的值,具体分析逻辑如下,这样就生成我们最后关于Hello World程序关于系统调用的相关指令。

屏幕快照 2019-08-20 下午10.12.24.png

汇编语言常用关键字

  • mov:表示move的意思就是移动数据,所以诸如如下语句

    • “move rax,1”的意思就是将ID为1的sys_write系统调用移动寄存器rax,那么你应该记住,以后遇到类似move rax ID这样格式的命令就应该记住这是通过寄存器执行某项系统调用
    • "move rsi text":的意思就是从text变量指定的内存位置加载字符串到rsi寄存器
  • syscall:每调用move指令后以syscall结尾,表示执行一次系统调用,也就是说你执行一个不同的系统调用都需要以syscall关键字结束。

  • 从上面的两点理解,应该不难看出"mov rax 60"这条指令是关于系统调用ID等于60(从网上查到是sys_exit),关于告知操作系统,你的程序已经执行完毕,同理,move rdi 0是执行与描述符有关的操作,即告知程序退出的状态 ,事实上这个状态码你可以任意定义的,按照程序设计的一般约定,0代表程序执行正常退出,其他为异常状态

  • section:所有x86_64的汇编文件有三种section

    • .data:该section下定义的所有变量,在汇编之前,编译器会完成所有相关变量指向对应内存位置的值的替换。你可以理解为C/C++的变量相关的操作。
    • .bss 该section,为某些功能的使用而分配内存,和.data section有些类似
    • .text 该section,主要定义程序运行的逻辑和各种的系统调用。
  • label:标签用于标记代码的一部分。在编译时,编译将计算标签在内存中的位置。 每次使用标签的名称后,该名称将被编译器替换为内存中的位置。如果你看看helloword定义text的位置,它基本上是相同的,除了我们可以在位置插入这些标签。在我们的代码中将会看到为什么它在将来会有用武之地。

    • _start:标签对所有程序都至关重要。当您编写程序并稍后执行时,它首先在“_start”的位置执行。如果链接器找不到“_start”标签,则会抛出错误。
    • global:当您希望链接器能够知道某个标签的地址时,使用global关键字。 生成的目标文件将包含指向“global”的每个标签的链接。在helloworld这个示例中,我们必须将“_start”声明为全局,因为代码必须正确链接。
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 199,175评论 5 466
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 83,674评论 2 376
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 146,151评论 0 328
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 53,597评论 1 269
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 62,505评论 5 359
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 47,969评论 1 275
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,455评论 3 390
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,118评论 0 254
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,227评论 1 294
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,213评论 2 317
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,214评论 1 328
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,928评论 3 316
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,512评论 3 302
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,616评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,848评论 1 255
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,228评论 2 344
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 41,772评论 2 339

推荐阅读更多精彩内容