我什么时候应该在 x86 中使用大小指令?

2023-12-27

何时在 x86 中使用大小指令似乎有点含糊。这个 x86 组装指南 http://www.cs.virginia.edu/~evans/cs216/guides/x86.html说如下:

一般来说,给定内存中数据项的预期大小 地址可以从它所在的汇编代码指令中推断出来 参考。例如,在上述所有指令中,大小 内存区域可以从寄存器的大小推断出来 操作数。当我们加载 32 位寄存器时,汇编器可以 推断我们所指的内存区域是 4 字节宽。 当我们将单字节寄存器的值存储到内存时, 汇编器可以推断我们希望该地址引用单个 内存中的字节。

他们给出的示例非常简单,例如将立即值移动到寄存器中。
但更复杂的情况又如何呢,例如:

mov    QWORD PTR [rip+0x21b520], 0x1

在这种情况下,QWORD PTR 大小指令不是多余的吗?因为根据上述指南,由于 RIP 是 8 字节,因此可以假设我们想要将 8 字节移动到目标寄存器中? x86 架构上大小指令的明确规则是什么?我在任何地方都找不到这个问题的答案,谢谢。

更新:正如罗斯指出的,上例中的目的地不是寄存器。这是一个更相关的示例:

mov    esi, DWORD PTR [rax*4+0x419260] 

在这种情况下,不能假设我们要移动 4 个字节,因为 ESI 是 4 个字节,从而使 DWORD PTR 指令变得多余吗?


你说得对;这是相当模糊的。假设我们谈论的是 Intel 语法,那么您确实经常可以逃脱惩罚not使用尺寸指令。只要汇编器可以自动计算出它,它们就是可选的。例如,在指令中

mov    esi, DWORD PTR [rax*4+0x419260] 

DWORD PTR 说明符是可选的,其原因正是您所想象的:汇编器可以确定要移动 DWORD 大小的值,因为该值正在移动到 DWORD 大小的寄存器中。

同样,在

mov    rsi, QWORD PTR [rax*4+0x419260] 

出于完全相同的原因,QWORD PTR 说明符是可选的。

但这并不总是可选的。考虑你的第一个例子:

mov    QWORD PTR [rip+0x21b520], 0x1

这里,QWORD PTR 说明符是not选修的。如果没有它,汇编器就不知道您要从该地址开始存储什么大小的值rip+0x21b520。应该0x1存储为 BYTE?扩展到一个WORD?一个双字? QWORD?一些汇编程序可能会猜测,但如果没有明确指定您想要的结果,您就无法保证正确的结果。

换句话说,当该值位于register对于操作数,大小说明符是可选的,因为汇编器可以根据寄存器的大小计算出大小。但是,如果您正在处理立即值或内存操作数,则可能需要大小说明符以确保获得所需的结果。

就我个人而言,我更喜欢always当我编写代码时包括大小。虽然多打了几个字符,但它迫使我思考并明确说明我想要什么。如果我搞砸了并且编写了不匹配的代码,那么汇编器就会对我大声尖叫,这已经不止一次地捕获了错误。我还认为将它放在那里可以增强可读性。所以在这里我同意老旧的计时器 https://stackoverflow.com/a/44577271/366904,尽管他的观点似乎有些不受欢迎。

反汇编程序的输出也往往很冗长,包括大小说明符,即使它们是可选的。 Hans Passant 在评论中推测这是为了保持与总是需要这些的老式汇编器的向后兼容性,但我不确定这是真的。这可能是其中的一部分,但根据我的经验,反汇编程序往往在lots不同的方式,我认为这只是为了更容易分析您不熟悉的代码。

请注意,AT&T 语法使用的策略略有不同。它不是将大小写为操作数的前缀,而是在指令助记符中添加后缀:b对于字节来说,w对于单词来说,l对于双字,以及q对于 qword。因此,前面的三个例子就变成了:

movl    0x419260(,%rax,4), %esi
movq    0x419260(,%rax,4), %rsi
movq    $0x1, 0x21b520(%rip)

同样,在前两条指令中,l and q前缀是可选的,因为汇编器可以推导出适当的大小。在最后一条指令上,就像英特尔语法一样,前缀是非可选的。因此,AT&T 语法与 Intel 语法相同,只是大小说明符的格式不同。

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

我什么时候应该在 x86 中使用大小指令? 的相关文章

  • 如何在 GCC C++ 中编写多行内联汇编代码?

    这看起来不太友好 asm command 1 command 2 command 3 我真的必须在每一行加上双引号吗 另外 由于多行字符串文字在 GCC 中不起作用 我也无法欺骗它 我总是在互联网上找到一些例子 该人手动插入制表符和换行符而
  • Core i3/5/7 CPU 是否提供测量 IPC 的机制?

    至少 过去十年中的所有英特尔 CPU 都包含一组对各种事件进行计数的性能监视器 最新的 Intel CPU Core i3 i5 和 i7 又名 Nehalem 是否提供了计算每时钟指令 IPC 的机制 如果有 它们是如何使用的 如果可能的
  • 调用可以是 cdecl 或 stdcall 的函数

    我需要编写调用外部函数的代码 该函数可以是 32 位 Windows 应用程序中的 stdcall 调用或 cdecl 我的代码 调用者 无法提前知道其中的哪一个 现在 如果我尝试从定义为 stdcall 的调用站点调用 cdecl 函数
  • PAE(物理地址扩展)如何实现大于4GB的地址空间?

    维基百科文章的摘录物理地址扩展 http en wikipedia org wiki Physical Address Extension x86 处理器硬件架构通过用于选择附加内存的附加地址线进行了增强 因此物理地址大小从 32 位增加到
  • 将 C 代码转换为 x86-64 汇编

    我正在尝试将 C 代码转换为 x86 64 我的目标是反转链表 传入的两个参数是 head ptr 和 offset to 以获取指针字段的地址 即指向列表中下一个节点的指针 据我了解 head ptr是通过rdi寄存器传入的 offset
  • Polygot 包含 nasm/yasm 和 C 的文件

    我有一堆幻数 我想将它们包含在由 nasm 或 yasm 编译的 C 程序和汇编文件中 在纯 C 语言中 该文件看起来像是一系列定义 例如 define BLESS 55378008 define ANSWER 42 在 nasm 或 ya
  • 从 DX:AX 寄存器转移到单个 32 位寄存器

    我在添加 16 位乘法的乘积时遇到问题 我想将一年 例如 2015 年 乘以 365 为此 我 mov dx 0 to clear the register mov ax cx cx holds the year such as 2015
  • 使用 ACPI 在 MS-DOS 中关闭计算机

    我在基于 Pentium 的计算机上运行 MS DOS 6 22 主板支持 ACPI 并且想知道是否有一个可以用来关闭计算机的汇编语言例程 或者它是否比那个更难 即主板 具体的 基本上 我想创建一个小程序来从命令行关闭计算机 这是专门为此编
  • 在 debian wheezy amd64 上安装 ia32-libs

    我正在使用 Debian 7 喘息 amd64 uname a Linux tzwm debian 3 2 0 4 amd64 1 SMP Debian 3 2 51 1 x86 64 GNU Linux 我想安装ia32 libs在我的
  • intfmt: db "%d", 10, 0 在汇编中的含义

    我最近在我的一个汇编文件的顶部看到了这个 并意识到我在打印整数的过程中花了很长时间使用它 而没有真正意识到它最初来自哪里 在我的基本汇编模板中使用 或 10 0 是什么结尾的意思是 section data intfmt db d 10 0
  • 错误:无法识别的指令 [ORG]

    我试图编写一个引导加载程序以在 dos box 中使用 我写了下面的代码 BITS 16 tell the assembler that its a 16 bit code ORG 0x7C00 Origin tell the assemb
  • 将以下机器语言代码(0x2237FFF1)翻译成MIPS汇编

    到目前为止我已经翻译了这段代码 但我不明白的是如何计算 计算 16 位立即地址的数量 0x2237FFF1 转为二进制 0010 0010 0011 0111 1111 1111 1111 0001 现在我正在读取操作码 001000 并知
  • 如何恢复 x86-64 寄存器保存约定

    fibonacci cmpq 1 rdi ja recursive movl 1 eax ret recursive push rbp push r10 movq rdi r10 leaq 2 rdi rdi call fibonacci
  • 如何在汇编中使用 ReadString?

    mov edx offset Prompt1 call WriteString mov ecx 32 mov edx offset String1 call ReadString 现在 我该如何访问String1 如何将其移入寄存器以便对其
  • 在现代 x86-64 上计算 64 位整数的整数 Log10 的最快方法是什么?

    标题 我找到了大量 32 位示例 但没有找到完整的 64 位示例 使用这个帖子 https codegolf stackexchange com questions 47290 fastest way to compute order of
  • 如何使 gcc 为 -fpatchable-function-entry 发出多字节 NOP?

    gcc确实有能力使用多字节用于对齐循环和函数的 NOP 然而当我尝试 fpatchable function entry option https gcc gnu org onlinedocs gcc Instrumentation Opt
  • 在共享库中不使用 PLT 的情况下调用另一个目标文件中的函数?

    我有两个汇编代码 code1 s and code2 s我想从这两个构建一个可重定位 使用 fPIC 开关 共享库 I want code2 s调用一个函数 名为myfun1 其定义在code1 s 当我使用call myfun1 PLT
  • x86:寄存器操作为内存内容和内存地址?

    寄存器 gt 内存地址 gt 内存内容 内存地址 gt 内存内容 上面的模型正确吗 而且 如果是的话 你能建议我是否认为正确吗 movl eax ebx gt 它将 eax 的内存地址移动到 ebx 这也会导致内容移动 movl eax e
  • 微软怎么能说WinAPI中一个字的大小是16位呢?

    我刚刚开始学习WinAPI 在MSDN中 对WORD数据类型提供了以下解释 WORD16 位无符号整数 范围是十进制 0 到 65535 该类型在 WinDef h 中声明如下 typedef 无符号短 WORD 很简单 而且它与我一直在使
  • 如何阅读英特尔操作码符号

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

随机推荐

  • 2D瓦片地图生成

    对于 2D 图块引擎 我正在研究地图生成算法 我尝试了高度图生成 山地一代 柏林噪声 菱形方形 适合具有高度组件的图块地图 但我有草 海 沙漠等精灵 它们的放置方式应如下所示 一切都从海洋开始 岛屿被放置在地图的中间 这是我尝试的算法大多失
  • 如何从随机网页中抓取文本和图像?

    我需要一种方法来直观地表示互联网上的随机网页 比如说this https www reddit com r food comments 85rm0d homemade chocolate banana bread with nuts 网页
  • 如何存储历史数据[关闭]

    Closed 这个问题需要细节或清晰度 help closed questions 目前不接受答案 我和一些同事就存储历史数据的最佳方式进行了争论 目前 对于某些系统 我使用单独的表来存储历史数据 并为当前活动记录保留原始表 所以 假设我有
  • 如何在android中的后者边界内打开另一个应用程序内的应用程序?

    如何在android中的后者边界内打开另一个应用程序内的应用程序 即 类似于 HTML 中的 iframe 的作用 你基本上不能 这违反了Android的规则 您最多能做的就是打开一个网页作为应用程序的一部分 这是使用 webView 完成
  • LevelDB 与 std::map

    在我们的应用程序中我们使用std map存储 键 值 数据并使用序列化将该数据存储在磁盘上 通过这种方法 我们发现磁盘 I O 是性能瓶颈 并且使用 key 查找值并不是很快 我遇到过 LevelDB 并考虑使用它 但我有一些问题 Leve
  • 为什么 `;;` 在 utop 中给我一个语法错误?

    我正在开发一个简短的项目 将小程序从 python 转换为 java 反之亦然 我创建了以下代码 并在 utop 中进行了测试 let c let x for int i 0 i lt 10 i and y for i in range 0
  • 在 bash 脚本/命令中,如何发出 PC 蜂鸣声或播放声音文件?

    我有一些长时间运行的脚本 需要输入 交互才能继续 但是当我切换到另一个窗口时 我希望收到 通过声音 通知任务已完成并且正在等待输入 我希望能够播放音频剪辑 mp3 ogg 等 但不关心唯一的解决方案是否是让 PC 扬声器发出蜂鸣声 有任何想
  • 如何从 UIView 类的 xib 文件导航到 ViewController

    我的 xib 文件中有一个包含按钮的视图 当我按下按钮时我想移动到 ViewController IBAction 我使用了下面的代码 let storyBoard UIStoryboard UIStoryboard name Main b
  • 从本地通知启动关闭的 iOS 应用程序

    当我的 iOS 应用程序在后台运行时 它响应良好 void application UIApplication application didReceiveLocalNotification UILocalNotification noti
  • Python 中的元组和 CSV 读取器

    尝试一些相对简单的事情 首先 我有一个以元组为键的字典 如下所示 0 1 1 0 索引 1 我正在读取一个 CSV 文件 该文件具有一组相应的字段 其中包含这些零和一的各种组合 例如 CSV 中的行可能会读取 0 1 1 0 而无需任何引号
  • 按值对 dict 进行排序,然后如果按键相等

    我创建了一个字典 键 列表中的单词值 它们的数量 想要按计数 值 对它们进行排序 那么如果计数相等 则按 alpha 键 对它们进行排序 a to be or not to be ae ae w for i in a w i a count
  • Java 中的嵌套枚举

    我想嵌套一些枚举 我代表的对象是标志 具有类型和值 有离散数量的类型 每种类型都有一组不同的可能值 因此 如果类型 A 可以有值 1 2 或 3 而类型 B 可以有值 4 5 6 我希望能够执行以下操作 Flag f Flag A 1 f
  • 我应该如何将 try-with-resources 与 JDBC 结合使用?

    我有一种使用 JDBC 从数据库获取用户的方法 public List
  • 如何在idea中调试play2?

    我在互联网上找到了一些文章和谷歌小组上的一些讨论 但它们不再起作用了 最新的play2 RC3如何做到这一点 您可以从控制台以调试模式启动播放服务器 docs http www playframework org documentation
  • 如何在 MATLAB 图形中设置子图大小?

    我经常需要将 10 个图像绘制在一起 但使用此代码会产生小图像 img rand 400 600 for i 1 10 subplot 2 5 i imshow img title Image int2str i end 正如您所看到的 图
  • 将 Selenium 与 Brave Browser 一起使用,传递用 python 编写的服务对象

    TLDR 我想使用勇敢的浏览器和用 python 编写的 selenium 但找不到任何当前有效的解决方案 这段代码有效 from selenium import webdriver option webdriver ChromeOptio
  • 如何在Thymeleaf和Spring Boot中显示消息?

    我创建了一个使用 Thymeleaf 作为模板引擎的 Spring Boot Web 应用程序 我配置了MessageSource在子文件夹中查找邮件 Bean public MessageSource messageSource fina
  • 在 Angular 2 模型驱动表单中设置选择控件的选定选项

    我在 SO 和其他地方研究了许多类似的现有答案 但就是找不到解决方案 我使用 Angular 2 中的模型驱动方法来构建我的表单 该表单既是添加表单又是编辑表单 在编辑模式下 这些值将填充从服务检索的数据 这方面一切都很好 因为简单的文本输
  • 如何显示存储在 SQLite 数据库中的 BLOB 图像?

    我有一个包含条目和 4 个按钮的 CRUD 表单删除 更新 创建 获取我的数据库中的值 我想实现另一个按钮来打开绑定到我的图像id entry也能够与我的合作删除 更新 创建 获取按钮 我一直在尝试使用 BLOB 并且能够将图像作为 BLO
  • 我什么时候应该在 x86 中使用大小指令?

    何时在 x86 中使用大小指令似乎有点含糊 这个 x86 组装指南 http www cs virginia edu evans cs216 guides x86 html说如下 一般来说 给定内存中数据项的预期大小 地址可以从它所在的汇编