为什么这个简单的汇编程序可以使用 AT&T 语法而不是 Intel 语法?

2023-12-29

这段代码有什么问题(在 x86_64 Linux 上运行)?

.intel_syntax
.text
.globl _start

_start:
    mov rax, 1
    mov rdi, 1
    mov rsi, msg
    mov rdx, 14
    syscall

    mov rax, 60
    mov rdi, 0
    syscall

.data
msg:
    .ascii "Hello, world!\n"

当我运行它时:

$ clang -o hello_intel hello_intel.s  -nostdlib  && ./hello_intel

无输出。让我们来看看:

$ strace ./hello_intel
execve("./hello_intel", ["./hello_intel"], [/* 96 vars */]) = 0
write(1, 0x77202c6f6c6c6548, 14)        = -1 EFAULT (Bad address)
exit(0)                                 = ?
+++ exited with 0 +++

它正在解除引用msg而不是使用它的位置。为什么?

如果我改用 AT&T 语法...

.text
.globl _start

_start:
    mov $1, %rax
    mov $1, %rdi
    mov $msg, %rsi
    mov $14, %rdx
    syscall

    mov $60, %rax
    mov $0, %rdi
    syscall

.data
msg:
    .ascii "Hello, world!\n"

...它工作正常:

$ clang -o hello_att hello_att.s  -nostdlib && ./hello_att
Hello, world!

这两者有什么区别?

这是工作的:

$ objdump -d hello_att -s -M intel

hello_att:     file format elf64-x86-64

Contents of section .text:
 4000e8 48c7c001 00000048 c7c70100 000048c7  H......H......H.
 4000f8 c6160160 0048c7c2 0e000000 0f0548c7  ...`.H........H.
 400108 c03c0000 0048c7c7 00000000 0f05      .<...H........  
Contents of section .data:
 600116 48656c6c 6f2c2077 6f726c64 210a      Hello, world!.  

Disassembly of section .text:

00000000004000e8 <_start>:
  4000e8:   48 c7 c0 01 00 00 00    mov    rax,0x1
  4000ef:   48 c7 c7 01 00 00 00    mov    rdi,0x1
  4000f6:   48 c7 c6 16 01 60 00    mov    rsi,0x600116
  4000fd:   48 c7 c2 0e 00 00 00    mov    rdx,0xe
  400104:   0f 05                   syscall 
  400106:   48 c7 c0 3c 00 00 00    mov    rax,0x3c
  40010d:   48 c7 c7 00 00 00 00    mov    rdi,0x0
  400114:   0f 05                   syscall 

这是损坏的:

$ objdump -d hello_intel -s -M intel

hello_intel:     file format elf64-x86-64

Contents of section .text:
 4000e8 48c7c001 00000048 c7c70100 0000488b  H......H......H.
 4000f8 34251701 600048c7 c20e0000 000f0548  4%..`.H........H
 400108 c7c03c00 000048c7 c7000000 000f05    ..<...H........ 
Contents of section .data:
 600117 48656c6c 6f2c2077 6f726c64 210a      Hello, world!.  

Disassembly of section .text:

00000000004000e8 <_start>:
  4000e8:   48 c7 c0 01 00 00 00    mov    rax,0x1
  4000ef:   48 c7 c7 01 00 00 00    mov    rdi,0x1
  4000f6:   48 8b 34 25 17 01 60    mov    rsi,QWORD PTR ds:0x600117
  4000fd:   00 
  4000fe:   48 c7 c2 0e 00 00 00    mov    rdx,0xe
  400105:   0f 05                   syscall 
  400107:   48 c7 c0 3c 00 00 00    mov    rax,0x3c
  40010e:   48 c7 c7 00 00 00 00    mov    rdi,0x0
  400115:   0f 05                   syscall 

所以这里重要的区别是0x600116 vs QWORD PTR ds:0x600117,这确实看起来像指针和取消引用指针之间的区别。

那么如何在Intel语法代码中不取消引用指针呢?


以下是在 GCC 中运行的代码:

.intel_syntax noprefix
.text
.globl _start

_start:
    mov rax, 1
    mov rdi, 1
    mov rsi, offset msg
    mov rdx, 14
    syscall

    mov rax, 60
    mov rdi, 0
    syscall

.data
msg:
    .ascii "Hello, world!\n"

这俩noprefixoffset必须添加。可悲的是这个不适用于 clang https://bugs.llvm.org/show_bug.cgi?id=32530:

hello_intel.s:8:24: error: unknown token in expression
    mov rsi, offset msg
                       ^

但是,您可以使用以下方法解决该问题lea代替mov:

lea rsi, [msg+rip]

这在 clang 和 gcc 中都有效。 (并且适用于位置无关的代码)。这是将静态地址放入寄存器的标准方法。

mov esi, imm32是对位置相关的 RIP 相对 LEA 的一个小优化,但是mov rsi, sign_extended_imm32与 LEA 的代码大小相同。这在 Clang 中显然是不可能的.intel_syntax, 尽管叮叮当当emits offset msg编译时:如何让“mov rdx, symbol”移动符号值而不是clang intel语法中符号地址处的值? https://stackoverflow.com/questions/58794762/how-to-get-mov-rdx-symbol-to-move-symbol-value-and-not-value-at-symbols-addr

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

为什么这个简单的汇编程序可以使用 AT&T 语法而不是 Intel 语法? 的相关文章

  • 在 vimrc 中切换匹配

    我的 vimrc 文件中有以下几行 hi ExtraWhitespace cterm NONE ctermbg green ctermfg green guibg green guifg green match ExtraWhitespac
  • 为什么使用signalfd无法捕获SIGSEGV?

    我的系统是ubuntu 12 04 我将示例修改为man 2 signalfd 并添加sigaddset mask SIGSEGV 在示例中 但我无法得到输出SIGSEGV被生成 这是一个错误吗glibc 源代码片段如下 sigemptys
  • 如何在 AVX/AVX2 中递增向量

    我想使用内在函数来增加 SIMD 向量的元素 最简单的方法似乎是为每个元素加 1 如下所示 note vec inc之前已设置为1 vec mm256 add epi16 vec vec inc 但是是否有任何特殊指令来增加向量 类似于in
  • Linux >2.6.33:可以使用 sendfile() 来实现更快的“猫”吗?

    必须将大量大文件连接成一个更大的单个文件 我们目前使用 cat file1 file2 output file but are wondering whether it could be done faster than with that
  • 有没有办法提高linux管道的性能?

    我正在尝试使用 64 位将超高速数据从一个应用程序传输到另一个应用程序CentOS http en wikipedia org wiki CentOS6 我使用以下方法进行了基准测试dd发现阻碍我的是管道而不是程序中的算法 我的目标是达到
  • 在现代 x86-64 上计算 64 位整数的整数 Log10 的最快方法是什么?

    标题 我找到了大量 32 位示例 但没有找到完整的 64 位示例 使用这个帖子 https codegolf stackexchange com questions 47290 fastest way to compute order of
  • 如何将命令输出作为多个参数传递给另一个命令

    我想将命令的每个输出作为多个参数传递给第二个命令 例如 grep pattern input returns file1 file2 file3 我想复制这些输出 例如 cp file1 file1 bac cp file2 file2 b
  • grep 彩色线条

    我编写了一个简单的 PHP shell 脚本 它解析文件并输出某些元素 它产生大量的输出 采用不同的 bash 颜色 绿色表示正常 黄色表示警告 红色表示错误等 在开发过程中我想过滤掉一些行 例如 所有包含红色文本的行 我可以使用grep
  • 在 Linux 服务器上创建和编辑 MS-Word 文档?

    希望开发处理文档的服务器端应用程序 源文档大多是MS Word 2003 2007 即MS版本的Docx 希望服务器应用程序能够在linux或windows上运行 想知道在linux下读写MS Word文件最好的工具或库是什么 兼容性是最重
  • Linux 上的“软/硬 nofile”是什么意思

    当我尝试在RedHat EL5上安装软件时 我得到了错误 软 硬nofile的期望值是4096 而默认值是1024 我设法增加了这个数字 但我不知道参数是什么 他们指的是软链接和硬链接吗 我改变的方法是 a 修改 etc security
  • 为什么 INT64_MIN 的定义不同?为什么他们的行为不同?

    The stdint h我公司的标题是 define INT64 MIN 9223372036854775808LL 但在我项目的一些代码中 一位程序员写道 undef INT64 MIN define INT64 MIN 92233720
  • 如何阅读英特尔操作码符号

    我正在阅读一些引用的材料Intel vol 2 SDM x86 手册 https www intel com content www us en developer articles technical intel sdm html关于汇编
  • GCC C++ pow 精度

    所以我在参加一个计算竞赛时 我注意到一个奇怪的错误 pow 26 2 总是返回 675 有时返回 674 即使正确答案是 676 pow 26 3 pow 26 4 等也会出现此类错误 经过比赛后的一些调试 我相信答案与 int 向下舍入的
  • Clang 与 CLion:无法获取编译器信息

    我尝试通过更改在 CLion 中从 gcc 切换到 clang工具链偏爱 但现在 cmake 失败并显示以下内容 Cannot get compiler information Compiler exited with error code
  • 具有重复符号的 C++ 插件库上的段错误

    我有一个跨平台 C 应用程序 它分为多个共享库 并从插件共享库加载附加功能 插件库应该是自包含的并自行运行 无需了解或依赖于调用应用程序 其中一个插件包含从主应用程序复制的代码 因此包含与引擎中的符号名称重复的符号名称 是的 我知道这通常是
  • 设置 Vim 背景颜色

    当我尝试更改背景颜色时 vimrc或者直接在 Vim 中使用以下命令 set background dark 这根本不影响我的背景 也没有light选项 不过 当我运行 gvim 时 看起来还不错 有没有办法在不更改 Konsole 设置的
  • “./somescript.sh”和“. ./somescript.sh”有什么区别

    今天我按照一些说明在 Linux 中安装软件 有一个需要首先运行的脚本 它设置一些环境变量 指令告诉我执行 setup sh 但是我执行时犯了一个错误 setup sh 所以环境没有设置 最后我注意到了这一点并继续进行 我想知道这两种调用脚
  • 使用 hcitool 扫描低功耗蓝牙?

    当我运行此命令时 BLE 设备扫描仅持续 5 秒 sudo timeout 5s hcitool i hci0 lescan 输出显示在终端屏幕中 但是 当我将输出重定向到文件以保存广告设备的地址时 每次运行该命令时 我都会发现该文件是空的
  • 将代码保存在 L1 缓存中

    我一直在阅读维基百科关于 K 编程语言的文章 http en wikipedia org wiki K programming language Performance characteristics这就是我所看到的 解释器的小尺寸和语言的
  • ARM 的内核 Oops 页面错误错误代码

    Oops 之后的错误代码给出了有关 ARM EX 中的恐慌的信息 Oops 17 1 PREEMPT SMP在这种情况下 17 给出了信息 在 x86 中它代表 bit 0 0 no page found 1 protection faul

随机推荐

  • 动态张量对齐/裁剪

    我在 TensorFlow 上实现了全卷积网络 它使用编码器 解码器结构 训练时 我始终使用相同的图像大小 224x224 使用随机裁剪 并且一切正常 在干扰阶段 我想一次预测一张图像 因为我想使用全图像 未裁剪 例如 这样的图像有大小 4
  • 如何从Delphi函数返回数组?

    我的应用程序中有一个函数需要返回一个数组 我在几个地方找到了如何通过声明数组类型来做到这一点 例如 type TStringArray array of string 然后声明我的函数 function SomeFunction SomeP
  • 无法使用python编辑hosts文件

    我正在尝试编写一个 python 脚本 它可以根据一天中的时间阻止网站 但我无法在 Windows 中编辑主机文件 即使以管理员身份运行 cmd 也是如此 这是代码 import time from datetime import date
  • 覆盖基本 localized.strings 文件

    有没有一种方法可以为项目中的多个目标提供一个基本 localized strings 文件 并且为每个目标提供第二个 localized string 文件 该文件将覆盖单个值并将其附加到基本文件中 EDIT 我希望我的应用程序有两个 st
  • 如何使用libgit2获取单个文件的差异?

    是否有一个函数相当于git diff FILE in libgit2 换句话说 如何有效地检索 a 的差异single文件没有libgit2查看工作目录中的其他文件 git diff FILE将显示您相对于索引所做的更改 这可以通过使用 l
  • 括号内的 Swift 类型

    今天我在玩 Swift 一些奇怪的类型开始出现 let flip Int random 2 or arc4random or rand whatever you prefer 如果我输入flip进入 Xcode 6 Beta 2 自动完成会
  • HDF5 C++ 接口:编写动态二维数组

    我正在使用HDF5 C API http www hdfgroup org HDF5 doc cpplus RM index html写入二维数组数据集文件 HDF 集团拥有一个创建的例子 ftp ftp hdfgroup org HDF5
  • 在 tikzDevice 中使用 tikzAnnotate 注释 ggplot2 图形

    我想用tikzDevice包括带注释的ggplot2中的图表Latex文档 tikzAnnotate帮助有一个如何将它与基本图形一起使用的示例 但如何将它与基于网格的绘图包一起使用 例如ggplot2 挑战似乎是 tikz 节点的定位 pl
  • 将基本路径传递给运行时加载的 swf

    我有一个 main swf 它加载 module swf 而 module swf 加载一些资源 module swf 独立工作 也需要在由 main swf 加载时工作 但不幸的是 当 main swf 加载时 module swf 找不
  • 如何在Java mongodb驱动程序中使用“_id”字段查询文档?

    我试图通过搜索 id 键来查找 MongoDB 中的文档 我的文档看起来像这样 id ObjectId 4f693d40e4b04cde19f17205 hostname hostnameGoesHere OSType OSTypeGoes
  • 缺少:房产 ID 之后

    我不明白我在这里做错了什么 第 3 行报告缺少 在属性 ID 之后 document ready function imagegallery img each function this css width 100 imagegallery
  • 如何防止按下按钮时活动加载两次

    如果我在第一次单击后立即按下按钮两次 我会尝试阻止活动加载两次 我有一个活动 点击按钮即可加载 比如说 myButton setOnClickListener new View OnClickListener public void onC
  • wpf 树视图 mvvm

    我正在尝试使用 mvvm 填充树视图 但树不显示任何数据 我有一个员工列表 它是我的虚拟机中的一个属性 其中包含员工数据 xaml如下
  • expressjs:如何重定向到处理程序中间的静态文件?

    我正在使用expressjs 我想做这样的事情 app post bla function req res next some code if cond req forward staticFile html 正如 Vadim 指出的 您可
  • 在 ActionScript3 中加密并在 asp.net c# 中解密

    我需要将数据从闪存发送到服务器 因此我正在寻找一个用于加密文本的闪存 ActionScript 3 0 脚本和一个用于解密文本的 C net 脚本 有人能帮我一下吗 查看 as3corelib 加密包 http code google co
  • 如何使用程序化 Spark 提交功能

    最近 2015 年春季 有一个功能显然旨在允许以编程方式提交 Spark 作业 这是吉拉https issues apache org jira browse SPARK 4924 https issues apache org jira
  • 如何要求抽象方法是协程?

    我如何要求抽象基类实现特定方法作为协程 例如 考虑这个 ABC import abc class Foo abc ABC abc abstractmethod async def func pass 现在 当我子类化并实例化它时 class
  • 如何使用 jQuery 将值记录到 Firebug 控制台?

    我只是想知道是否有一种方法可以使用 jQuery 将一些变量值记录到 Firebug 控制台以进行调试 jQuery 只是一个 JavaScript 库 因此您可以使用console log http getfirebug com logg
  • Spring Webclient:非法参数异常没有足够的变量来扩展“comment_count”

    我正在使用 spring webclient 发出 Facebook graph api 请求 其 url 包含 comment count 但是 得到这个例外 java lang IllegalArgumentException Not
  • 为什么这个简单的汇编程序可以使用 AT&T 语法而不是 Intel 语法?

    这段代码有什么问题 在 x86 64 Linux 上运行 intel syntax text globl start start mov rax 1 mov rdi 1 mov rsi msg mov rdx 14 syscall mov