使用多秒后出现分段错误

2024-01-07

我对汇编完全是菜鸟,我尝试创建函数并在 C 中使用它。这个函数获取 3 个变量 a、x、y,它们是包含两个 64 位 int 的结构。我想返回a+x*y。不幸的是,这段代码是 NASM 导致段错误

%define a1 [rdi]
%define a2 [rdi+8]
%define x1 [rsi]
%define x2 [rsi+8]
%define y1 [rdx]
%define y2 [rdx+8]
%define output1 rax
%define output2 rdx
%define res1 r8
%define res2 r9

global abc

abc:

mov output1, x1
mul qword y1
mov res1, output1
mov output1, x1
mul qword y2
mov res2, output1
mov output1, x2
mul qword y1
add res2, output1
mov output1, res1
mov output2, res2


ret

删除第二个和第三个 mul 的行允许我运行我的程序而不会出现段错误。


如果你解开上面的宏定义,你最终会得到这样的结果,这就是处理器实际上试图执行的:

mov rax, [rsi]
mul qword [rdx]      <--- no segfault here
mov r8, rax
mov rax, [rsi]
mul qword [rdx+8]    <--- segfault here
mov r9, rax
mov rax, [rsi+8]
mul qword [rdx]      <--- segfault here
add r8, rax
mov rax, r8
mov rdx, r9

您说分段错误发生在上面标记的行上。

因此,让我们进行一些心灵调试(Raymond Chen 最喜欢的调试类型之一)。考虑第一次之后会发生什么mul操作说明:rax设置为产品的下部,并且rdx设置为产品的高部分。

这意味着在第一次之后mul, rdx已经改变!它不再是一个指向y1 or to y2,而是与 x1*y1 结果有关。在此之后的任何连续尝试都可以使用rdx作为一个指针肯定会失败,因为它不再是一个指针了。

所以为了解决这个问题,你必须保留rdx跨越另一个寄存器中的乘法。r10此代码未使用它,并且它被认为是易失性的,因此我们可以安全地使用它来存储初始值的“备份”rdx。所以这样的事情可能足以解决这个问题:

%define a1 [rdi]
%define a2 [rdi+8]
%define x1 [rsi]
%define x2 [rsi+8]
%define y1 [r10]         ; Change which register we're using as the
%define y2 [r10+8]       ; pointer to 'r10'.
%define output1 rax
%define output2 rdx
%define res1 r8
%define res2 r9

global abc

abc:
    mov r10, rdx         ; Preserve the real pointer to 'y1' in 'r10'.

    mov output1, x1
    mul qword y1
    mov res1, output1
    mov output1, x1
    mul qword y2
    mov res2, output1
    mov output1, x2
    mul qword y1
    add res2, output1
    mov output1, res1
    mov output2, res2

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

使用多秒后出现分段错误 的相关文章

  • 汇编-符号标志和奇偶校验标志

    我不明白什么时候设置标志标志 什么时候设置奇偶校验 据我所知 符号标志表示运算结果的符号 0表示正数 1表示负数 那么为什么在下一个代码中 mov al 5 sub al 124 SF为零 结果是负数 关于PF 为什么a和b中设置了PF a
  • CALL指令是否总是将EIP指向的地址压入堆栈?

    x86架构中函数调用时是否存在返回地址不入栈的情况 No CALL根据定义 将在跳转到目标地址之前将返回地址压入堆栈 该返回地址是EIP or RIP sizeof call instruction 通常为 5 个字节 英特尔 64 和 I
  • Visual Studio 2017 上的简单装配程序

    386 model flat c stack 100h printf PROTO arg1 Ptr Byte data msg1 byte Hello World 0Ah 0 code main proc INVOKE printf ADD
  • 为什么 Visual Studio 使用 xchg ax,ax

    我正在查看程序的反汇编 因为它崩溃了 并注意到很多 xchg ax ax 我用谷歌搜索了一下 发现它本质上是一个 nop 但是为什么 Visual Studio 会执行 xchg 而不是 noop 该应用程序是一个C NET3 5 64位应
  • 在linux x86平台上学习ARM所需的工具[关闭]

    Closed 此问题正在寻求书籍 工具 软件库等的推荐 不满足堆栈溢出指南 help closed questions 目前不接受答案 我有一个 x86 linux 机器 在阅读一些关于 ARM 的各种信息时 我很好奇 现在我想花一些时间学
  • 为什么 RISC-V S-B 和 U-J 指令类型以这种方式编码?

    我正在读一本书 计算机组织与设计RISC V版 我遇到了 S B 和 U J 指令类型的编码 我上面提到的那些类型有奇怪的编码立即字段 S B 类型将直接字段分为两部分 这是有道理的 因为所有指令编码都必须相似 但我无法理解为什么立即字段以
  • 两个基本的 ANTLR 问题

    我正在尝试使用 ANTLR 来获取简单的语法并生成汇编输出 我在 ANTLR 中选择的语言是 Python 许多教程看起来非常复杂或详细阐述与我无关的事情 我真的只需要一些非常简单的功能 所以我有两个问题 将值从一个规则 返回 到另一规则
  • 汇编8086监听键盘中断

    我有与此完全相同的问题 边画边听键盘 https stackoverflow com questions 13970325 8086 listen to keyboard while drawing 但第一个答案 接受的答案 只听键盘一次
  • 使用 Easy 68K (68000) 组装范围内的随机数

    我正在使用 Easy 68K 模拟器创建一个简单的黑杰克游戏 需要使用随机数来分配牌 我的牌必须在 2 到 11 的范围内 我似乎每次都得到相同的数字 但它不在我预期的范围内 我的卡值需要以 D3 结束 因此我有以下随机数代码 CLR L
  • 68HC11计算sin(x)的汇编代码

    68HC11 使用泰勒级数或查找表计算正弦值的汇编代码是什么 显示值只能是整数 查找表如何工作 在这种情况下 如何使用它来实现泰勒级数 http en wikipedia org wiki Taylor series 如果您正在寻找浮点解决
  • 寄存器寻址模式与直接寻址模式

    我在试卷中遇到过这个问题 它指出 哪种给定的寻址模式更快 为什么 寄存器寻址方式 直接寻址方式 现在根据我的说法 寄存器寻址模式应该更快 因为寄存器是计算机中最快的存储位置 这是正确答案吗 请帮忙 谢谢 两种寻址模式之间的区别是 地址的来源
  • “rep stos”x86 汇编指令序列有什么作用?

    我最近偶然发现了以下汇编指令序列 rep stos dword ptr edi For ecx重复 存储内容eax到哪里edi指向 递增或递减edi 取决于方向标志 每次 4 个字节 通常 这用于memset型操作 通常 该指令简单地写成r
  • ARMv8 A64 汇编中立即值的范围

    我的理解是 ARMv8 A64 汇编中的立即参数可以是 12 位长 如果是这样的话 为什么这行汇编代码是 AND X12 X10 0xFEF 产生此错误 使用 gcc 编译时 Error immediate out of range at
  • 阴影空间示例

    EDIT 我接受了下面的答案 并添加了我自己的代码的最终修订版 希望它向人们展示影子空间分配的实际示例 而不是更多的文字 编辑 2 我还设法在 YouTube 视频 所有内容 的注释中找到了一个调用约定 PDF 的链接 其中有一些关于 Li
  • 这种没有推送寄存器的交换有多安全?

    我对汇编非常陌生 下面的代码应该通过两个不同的函数交换两个整数 首先使用swap c然后使用swap asm 但我怀疑 我是否需要push 我的意思是保存 汇编代码之前寄存器的每个值和pop稍后 就在返回之前 main 换句话说 如果我返回
  • 在 x86 程序集中存储大量布尔值的最佳方法是什么?

    最近我一直在处理充满布尔值的大型数组 目前 我将它们存储在 bss部分有一个 space指令 它允许我创建字节数组 但是 由于我只需要存储布尔值 因此我希望从数组中逐位读取和写入数据 目前 我能想到的最好方法是有一个 space指令所需存储
  • 为什么我的代码显示垃圾?

    当我也想打印列表中的每个数字时 我的代码显示垃圾 有什么问题吗 输出应如下所示 给定的数组是 2G 4 PT为什么这是垃圾总数是 7 Code ASSUME CS CODE DS DATA SS STK ORG 0000H DATA SEG
  • 32位PPC rlwinm指令

    我在理解上有点困难rlwinmPPC 汇编指令 旋转左字立即然后与掩码 我正在尝试反转函数的这一部分 rlwinm r3 r3 0 28 28 我已经知道什么了r3 is r3在本例中是一个 4 字节整数 但我不确定这条指令到底是什么rlw
  • 32 位到 64 位内联汇编移植

    我有一段 C 代码 在 GNU Linux 环境下用 g 编译 它加载一个函数指针 它如何执行并不重要 使用一些内联汇编将一些参数推送到堆栈上 然后调用该函数 代码如下 unsigned long stack 1 23 33 43 save
  • Intel:序列化指令和分支预测

    英特尔架构开发人员手册 http www intel com content www us en architecture and technology 64 ia 32 architectures software developer v

随机推荐

  • AWS EB、Play Framework 和 Docker:应用程序已在运行

    我正在 AWS Elastic Beanstalk 上运行 Play 2 2 3 Web 应用程序 使用 SBT 功能生成 Docker 映像 从 EB 管理界面上传图像通常可以正常工作 但有时会出现持续出现以下错误的状态 Docker 容
  • 在 Prolog 中使用列表列表

    请帮我解决这个问题 我有一个清单清单 1 2 3 4 如何得到 1 3 1 4 2 3 2 4 或者如果我有一个列表列表 1 2 3 4 6 7 如何得到 1 3 6 1 3 7 1 4 6 1 4 7 2 3 6 2 3 7 2 4 6
  • 编写 Spring AOP 程序的 Maven 依赖项?

    我正在尝试使用 Spring 5 学习 Spring AOP 编程 我正在浏览在线材料 我发现AOP是一个概念 和OOP类似 有了 AOP OOP 就变得更加强大 现在 我正在尝试使用 Spring 框架版本 5 为 AOP 进行一些实践编
  • 为什么 Database First EF 会跳过映射某些表?

    我正在使用 Entity Framework 4 和 Database First 绑定 并且 EF 不会为我的一些表生成实体 我没有收到任何错误 并且无论我从设计界面上的 从数据库更新模型 弹出菜单中选择要生成的表多少次 模型中仍然缺少相
  • Android Edittext-清除跨度

    我试图通过调用来让 EditText 清除其跨度EditText getText clearSpans 但是 如果我调用此方法 EditText 就会开始表现得很奇怪 换行符显示为框 然后我设置的任何跨度都位于完全错误的位置 所以我的问题是
  • 否则,请避免更改日期格式[重复]

    这个问题在这里已经有答案了 我正在尝试为两个日期制作 if else 我有两列 日期和日期 我需要添加第三个变量 如果有日期值 它将显示 DateOut 如果有 它将显示 DateIn DateIn DateOut Travel date
  • 如何在 C++ 模板中执行 if else 依赖类型的类型? [复制]

    这个问题在这里已经有答案了 template specialization include
  • 带有锚元素的 jQuery mailto

    我用我们在网上看到的无数例子进行了尝试 但我想没有一个是简单的并且适用于所有浏览器 IE 8 及更高版本 我试图简单地打开带有 mailto 链接的 Outlook 窗口 a href Email a JQuery function ema
  • 如何“遍历”LINQ 中表之间的关系?

    假设我有三张表 Office ID SalespeopleOffice ID OfficeID PersonID People ID ManagerID 在 LINQ to SQL 中 我如何从SalespeopleOffices表并从该表
  • 是什么原因导致 java.lang.IllegalStateException: 无法加载 ApplicationContext 错误?

    我是 Spring Boot 的新手 所以我不明白是什么导致了上面提到的错误 因为所有内容都没有发出警告并且是从官方库导入的 import org junit jupiter api Assertions import org junit
  • 命名:解决方案、项目、命名空间和程序集

    我正在研究解决方案 项目 其默认命名空间和程序集的命名指南 Visual Studio 现在看起来像这样 例如 我们有一个名为 Company 的公司和一个名为 Project 的项目 该项目的业务逻辑位于单独的 dll UI WPF Wi
  • Cocoapods 安装出现错误 [重复]

    这个问题在这里已经有答案了 这是我的 Podfile platform ios 7 0 pod ECSlidingViewController gt 2 0 0 当我在终端中输入 pod install 时 出现以下错误 Invalid P
  • 查询活动目录以直接获取可分辨名称的电子邮件属性?

    我现在正在活动目录中进行一些查询 我们的数据库用户 ID 与活动目录用户 ID 相匹配 我将用户 ID 与域和路径一起传递以获取我需要的内容 我的努力是从传递的用户 ID 中获取经理的电子邮件地址 当我获得经理属性时 我返回的是专有名称 在
  • 如何使用工具栏选项在 Quill js 上添加字体类型?

    我制作了一个富文本区域Quill js https quilljs com 我的工具栏有以下选项 new Quill quilljs container modules toolbar bold italic underline strik
  • 如果 Blob 名称存在,Azure Blob 上传重命名

    在 Azure Blob 上传中 如果上传具有相同文件名 在同一容器中 的新文件 文件将被覆盖 我想在保存新文件之前重命名它 以避免覆盖任何文件 这可能吗 设想 将文件 Image jpg 上传到容器 mycontainer 将文件 Ima
  • Visual C++ 编译器优化

    我最近从 Dev c 迁移到 Visual C 2010 发现除了一个方面之外 它在所有方面都更好 当我使用 Dev c 编译并执行代码时best optimization选项切换后 编译时间大大减少 几乎减少了一半 mingw32 但我在
  • numpy 数组的并行就地排序

    我经常需要对大型 numpy 数组 几十亿个元素 进行排序 这成为我的代码的瓶颈 我正在寻找一种并行化它的方法 是否有任何并行实现ndarray sort 功能 Numexpr 模块为 numpy 数组上的大多数数学运算提供并行实现 但缺乏
  • 如何删除谷歌文档查看器中的弹出图标?

    我正在 android 中使用 google docsviewer 来显示 pdf 我想删除弹出选项 请参阅随附的屏幕截图 谷歌文档截图 https i stack imgur com XoU0a png 这是我用来加载 webview 的
  • 如何加快 Visual Studio 构建速度以匹配 MSBuild 并行性能?

    当一次使用 Devenv 构建相同的解决方案而另一次使用 msbuild m 构建相同的解决方案时 我遇到了明显的速度差异 作为信息 我已将 Visual Studio 中的参数 并行构建进程数 设置为 4 是否有可能加快 Visual S
  • 使用多秒后出现分段错误

    我对汇编完全是菜鸟 我尝试创建函数并在 C 中使用它 这个函数获取 3 个变量 a x y 它们是包含两个 64 位 int 的结构 我想返回a x y 不幸的是 这段代码是 NASM 导致段错误 define a1 rdi define