专栏首页Linux内核及编程语言底层相关技术研究如何找到linux内核中at&t风格的汇编指令最权威最详细的文档

如何找到linux内核中at&t风格的汇编指令最权威最详细的文档

汇编的语法风格分为两种,一种是intel风格,一种是at&t风格,intel风格主要用于windows平台,at&t风格主要用于unix平台。

因为linux是类unix型的操作系统,所以其内核中的汇编代码也是使用的at&t风格。

在编译linux内核时,默认使用的编译器是gcc,当涉及到内核汇编代码的编译时,gcc通过调用gnu的as命令来完成,as命令官方文档地址如下:

https://sourceware.org/binutils/docs-2.34/as/index.html

既然linux内核的汇编代码是根据as命令指定的格式编写的,那理论上来说,as的官方文档中应该有at&t风格的汇编指令的相关描述。

可惜并没有。

这种情况下,当我们在看linux内核的汇编代码时,只能通过阅读在网上找到的一些零散的at&t风格的汇编文档,以此来尝试理解内核逻辑。

但很多时候,这些文档并不能给出一个精准全面的解释,致使我们有时无法真正理解内核代码的用意。

那到哪里才能找到最精确,最全面的汇编指令相关解释呢?

下面我们来说个方法。

我们知道,不管是at&t风格,还是intel风格,最终这些汇编代码都会被编译成cpu可识别的二进制编码的机器指令,这个是唯一的,是不会随着汇编代码写法风格的改变而改变的。

对于x86型的cpu来说,其可识别的汇编指令,及该指令对应的编码格式的最权威最详细的文档介绍,莫过于 Intel® 64 and IA-32 Architectures Software Developer’s Manual 文档了,其官方地址如下:

https://software.intel.com/sites/default/files/managed/39/c5/325462-sdm-vol-1-2abcd-3abcd.pdf

在我们阅读linux内核代码的过程中,当遇到有疑问的at&t风格的汇编指令时,我们只需要查看该汇编指令编译后的二进制格式的机器指令,然后通过这些机器指令数据,在上面的intel sdm文档中找到对应的intel汇编指令,这样我们就算是找到了该at&t风格的汇编指令最精确最权威的定义了。

我们举个例子看下。

如果没有使用boot loader,比如grub,而是直接启动编译好的linux内核,执行的第一条汇编指令是ljmp:

假设我们对这条指令有些疑问,想看下其具体的文档说明,下面来看下要怎么做。

首先,我们用objdump反编译下这部分代码,查看其编译后的机器指令是什么样的:

$ objdump -S arch/x86/boot/setup.elf | more

其输出如下:

linux内核编译后的可运行文件是bzImage,而setup.elf正是bzImage文件的开始部分,所以我们上面是objdump的setup.elf,而不是bzImage。

我们用以下命令再确认下setup.elf确实是bzImage的开始部分:

对比以上两个图片,我们会发现它们的字节顺序及内容都是一样的,所以确定了我们上面的说法。

我们再继续看第一个图片中的反编译内容。

该内容中,前两个字节分别是4d 5a,其对应为内核代码中MZ_MAGIC宏的定义:

// include/linux/pe.h#define MZ_MAGIC        0x5a4d  /* "MZ" */

由上可见,MZ_MAGIC宏的值是0x5a4d,这个和我们反编译出来的字节顺序正好相反,这说明我们用的机器是小端模式。

接下来再看ljmp指令对应的字节内容:ea 07 00 c0 07。

由intel sdm文档可知,ea 对应的汇编指令可能有下面两种情况(选中行):

我们再对应看下文档中描述的 ea 后面的 cd 和 cp 的定义:

由上可知,cd 和 cp 分别表示该汇编指令(ea)后会有4个字节或6个字节的操作数。

结合我们上面反编译后的ljmp指令的字节数据 ea 07 00 c0 07,以及内核初始是在16位的real-address mode下执行,我们可以最终得到结论,该 ljmp 指令对应的就是上面 ea cd 代表的那行 intel 汇编指令 JMP ptr16:16。

该指令表示其是一次 far jump,看下其更详细的描述:

由上可知,我们要jump到的目标,是由segment selector和offset组成的一个4个字节的数值。

再结合最开始提到的,这条ljmp指令的原始代码是 ljmp $BOOTSEG, $start2,我们可根据BOOTSEG的值0x07C0和start2的值 0x0007(由反汇编结果得到),最终拼出一个4个byte组成的值 07 C0 00 07。

又由于我们是小端模式,所以该值在存储时要把顺序反过来,最终值为 07 00 C0 07。

再加上ljmp对应的值 ea,最终这条ljmp指令编译后的字节顺序应该为 ea 07 00 c0 07,对比一下上面反汇编的字节顺序:

是不是刚好一样。这就进一步确认了,我们找到的ljmp对应的intel汇编指令是正确的。

通过这种方式,我们就可以找到任意at&t风格的汇编指令最权威,最详尽的描述了。

好了,就这些,希望对你有所帮助。

本文分享自微信公众号 - Linux内核及JVM底层相关技术研究(ytcode),作者:wangyuntao

原文出处及转载信息见文内详细说明,如有侵权,请联系 yunjia_community@tencent.com 删除。

原始发表时间:2020-04-18

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • Linux内核源码规范解析

    曾经在开发Linux内核驱动的时候,创建了一个补丁文件,但是在把补丁打到主分支的时候提示很多编码风格的错误问题,后来重做了补丁才解决了问题,这也是没有严格按照的...

    范蠡
  • Win32 Linux汇编语法区别

    一、简介 作为最基本的编程语言之一,汇编语言虽然应用的范围不算很广,但重要性却勿庸置疑,因为它能够完成许多其它语言所无法完成的功能。就拿 Linux 内...

    ke1th
  • 如何优雅的调试段错误

    摘要:当程序运行出现段错误时,目标文件没有调试符号,也没配置产生 core dump,如何定位到出错的文件和函数,并尽可能提供更详细的一些信息,如参数,代码等...

    F-Stack
  • Github开源免费编程书籍

    时见疏星
  • 一些免费的学习资源 原

    HTML5 Canvas编程:http://blog.csdn.net/column/details/canvas-programming.html GTK编...

    wuweixiang
  • X86 寻址方式、AT&T 汇编语言相关知识、AT&T 与 Intel 汇编语言的比较、gcc 嵌入式汇编

    注:本分类下文章大多整理自《深入分析linux内核源代码》一书,另有参考其他一些资料如《linux内核完全剖析》、《linux c 编程一站式学习》等,只是为了...

    s1mba
  • AT&T与Intel汇编语言的比较

    转自陈莉君一书《深入分析Linux内核源码》http://www.kerneltravel.ne运维

    Java架构师必看
  • GCC内嵌汇编语言

    绝大多数 Linux 程序员以前只接触过DOS/Windows 下的汇编语言,这些汇编代码都是 Intel 风格的。但在 Unix 和 Linux 系统中,更多...

    ternturing
  • Web-第十九天 Linux学习【悟空教程】

    UNIX操作系统是商业版,需要收费,价格比Microsoft Windows正版要贵一些。不过UNIX有免费版的,例如:NetBSD等类似UNIX版本。

    Java帮帮
  • 初识Linux渗透:从枚举到内核利用

    许多人都认为Linux是最安全的操作系统,因此在对Linux的安全问题上也放松了警惕。那么事实真的如此吗?其实安全从来都只是相对的,Linux也不例外。虽然它加...

    FB客服
  • Linux新手渗透指南:从枚举到内核利用

    许多人都认为Linux是最安全的操作系统,因此在对Linux的安全问题上也放松了警惕。那么事实真的如此吗?其实安全从来都只是相对的,Linux也不例外。虽然它加...

    C4rpeDime
  • PWN学习指南

    C:c语言是必须得会的。推荐书籍《c程序设计语言》,也可以看看网课,中国大学mooc,b站上都有很多的资源。 C++ :推荐先看基础网课,然后再看《c++ pr...

    HACK学习
  • 程序的编译、链接、装载与运行

    在Linux操作系统中,一段C程序从被写下到最终被CPU执行,要经过一段漫长而又复杂的过程。下图展示了这个过程

    shengjk1
  • 97 条 Linux 运维工程师常用命令总结 | 史上最全Linux命令总结

    先说明一下,这篇文章只是一篇常用基础命令的汇总,小白可以看着学习一下,对大牛帮助不大。。。。

    谭庆波
  • 97 条 Linux 运维工程师常用命令总结

    作者:jeanheo 1.ls [选项] [目录名 | 列出相关目录下的所有目录和文件 -a 列出包括.a开头的隐藏文件的所有文件 -A 通-a,但不列出...

    小小科
  • 黑科技抢先尝 - Windows全新终端初体验(附代码Build全过程)

    版权声明:本文为博主Bravo Yeung(微信公众号dotNET匠人, 知乎Bravo Yeung...

    Enjoy233
  • 嵌入式裸板学习之基础知识

    简介 数据在内存中以字节形式存放,X86结构是小端模式,而KEIL C51则为大端模式。很多的ARM,DSP都为小端模式。有些ARM处理器还可以随时在程序中(在...

    嵌入式与Linux那些事
  • linux学习--未整理命令

    find /path -type f -exec rm -f {} ; 删除指定文件

    solate
  • eBPF技术简介

    “eBPF 是我见过的 Linux 中最神奇的技术,没有之一,已成为 Linux 内核中顶级子模块,从 tcpdump 中用作网络包过滤的经典 cbpf,到成为...

    CNCF

扫码关注云+社区

领取腾讯云代金券