如何使用 AVR 的 gnu 汇编器相对于 PC 跳转?

2023-12-13

我有一个使用 avr-objcopy 反汇编的二进制文件。中断向量表如下所示:



00000000 :
    ; VECTOR TABLE
   0:   13 c0           rjmp    .+38        ;  0x28, RESET
   2:   b8 c1           rjmp    .+880       ;  0x374, INT0
   4:   fd cf           rjmp    .-6         ;  0x0
   6:   fc cf           rjmp    .-8         ;  0x0
   8:   fb cf           rjmp    .-10        ;  0x0
   a:   fa cf           rjmp    .-12        ;  0x0
   c:   f9 cf           rjmp    .-14        ;  0x0
   e:   f8 cf           rjmp    .-16        ;  0x0
  10:   f7 cf           rjmp    .-18        ;  0x0
  12:   c7 c1           rjmp    .+910       ;  0x3a2, TIMER1 OVF
  14:   f5 cf           rjmp    .-22        ;  0x0
  16:   f4 cf           rjmp    .-24        ;  0x0
  18:   f3 cf           rjmp    .-26        ;  0x0
  1a:   f2 cf           rjmp    .-28        ;  0x0
  1c:   2b c2           rjmp    .+1110      ;  0x474, ADC conversion complete
  1e:   f0 cf           rjmp    .-32        ;  0x0
  20:   ef cf           rjmp    .-34        ;  0x0
  22:   ee cf           rjmp    .-36        ;  0x0
  24:   ed cf           rjmp    .-38        ;  0x0
  26:   00 00           nop
  ; START
  28:   f8 94           cli
 (snip)  

我想通过一些修改重新组装该文件。我通过删除前两列对其进行了重新格式化,使其成为常规的汇编文件。 IE:



.org 0
    rjmp    .+38            ;  0x28, RESET
    rjmp    .+880           ;  0x374, INT0
(snip)  

然而,当我跑步时


$ avr-as -mmcu=atmega8 test.asm  

然后反汇编生成的文件。 (使用 objcopy -S a.out)输出如下所示:


00000000 :
   0:   00 c0           rjmp    .+0             ;  0x2
   2:   00 c0           rjmp    .+0             ;  0x4
   4:   00 c0           rjmp    .+0             ;  0x6
   6:   00 c0           rjmp    .+0             ;  0x8
   8:   00 c0           rjmp    .+0             ;  0xa
   a:   00 c0           rjmp    .+0             ;  0xc
   c:   00 c0           rjmp    .+0             ;  0xe
   e:   00 c0           rjmp    .+0             ;  0x10
  10:   00 c0           rjmp    .+0             ;  0x12
  12:   00 c0           rjmp    .+0             ;  0x14
  14:   00 c0           rjmp    .+0             ;  0x16
  16:   00 c0           rjmp    .+0             ;  0x18
  18:   00 c0           rjmp    .+0             ;  0x1a
  1a:   00 c0           rjmp    .+0             ;  0x1c
  1c:   00 c0           rjmp    .+0             ;  0x1e
  1e:   00 c0           rjmp    .+0             ;  0x20
  20:   00 c0           rjmp    .+0             ;  0x22
  22:   00 c0           rjmp    .+0             ;  0x24
  24:   00 c0           rjmp    .+0             ;  0x26
  26:   00 00           nop
  28:   f8 94           cli
(snip)
  

那么我怎样才能让 avr-as 尊重 PC 相对跳转呢?


我找到了答案!

我正在组装但没有链接。因此汇编器用 .+0 填充所有相对跳转/调用/分支。

为了解决这个问题,我需要创建一个名为 linker.x 的自定义链接器脚本,其中包含以下内容:



SECTIONS
{
  . = 0x0;
  .text : { *(.text) }
}
  

这告诉链接器从地址 0 开始 .text 节。

然后我可以使用以下方式链接代码:

$ avr-ld -mavr4 -Tlinker.x a.out -o output.o

使用上述命令链接后,所有 .+0 都已填充正确的值!

这样做的原因是因为在链接阶段之前,as/gcc 不知道二进制文件中还将包含什么。它是一个链接器,它获取所有单独的目标文件并将它们组合成一个。因此,如果链接器阶段从未运行,则无法用绝对跳转来填充相对跳转。

AVR 的汇编器负责汇编和链接。但 gnu 汇编器更通用,因此您需要单独链接。

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

如何使用 AVR 的 gnu 汇编器相对于 PC 跳转? 的相关文章

  • 编写 AMD64 SysV 程序集时使用哪些寄存器作为临时寄存器?

    我正在使用实现一个功能cpuid根据 AMD64 SysV ABI 进行组装 我需要在函数本身中使用 2 个临时寄存器 第一个用于累积返回值 第二个用作计数器 我的功能目前如下所示 zero argument function some c
  • 为什么我可以使用 ret 退出 main?

    我即将弄清楚程序堆栈到底是如何设置的 我了解到用以下方式调用该函数 call pointer 实际上等同于 mov register pc programcounter add register 1 where 1 is one instr
  • 这段汇编语言代码是什么意思?

    我是一名学生 刚刚开始学习汇编语言 为了更好地理解它 我只是用 C 写了一个简短的代码并将其转换为汇编语言 奇怪的是我有点听不懂 代码是 include
  • 什么时候汇编比C更快? [关闭]

    Closed 这个问题需要多问focused help closed questions 目前不接受答案 Locked 这个问题及其答案是locked help locked posts因为这个问题是题外话 但却具有历史意义 目前不接受新的
  • 减法进位标志

    我正在使用 MASM32 有了这个代码 mov eax 5 sub eax 10 CF 状态标志将被设置 但使用我的铅笔和纸 我实际上看到 MSB 没有任何进位 是的 我知道从较少的数字中减去大的数字集CF 但我想知道为什么 因为使用这段代
  • 在 x86-64 CPU 上通过交叉修改代码重现意外行为

    Question 对于可能在 x86 或 x86 x64 系统上触发意外行为的交叉修改代码有哪些想法 在这些系统中 交叉修改代码中的所有操作均已正确完成 但在执行处理器之前执行序列化指令除外修改代码 如下所述 我有一个 Core 2 Duo
  • 为什么当大小大于 50 时,该程序花费的时间会呈指数级增长?

    所以我正在为类编写一个 ARM 汇编快速排序方法 我对大部分内容都有了解 除了复杂性没有意义 我们将其与我们制作的另一种冒泡排序方法进行比较 它对于具有 1 个参数和 10 个参数的示例表现更好 然而 我什至无法比较 100 个参数测试 因
  • Nasm 打印到下一行

    我用 nasm Assembly 编写了以下程序 section text global start start Input variables mov edx inLen mov ecx inMsg mov ebx 1 mov eax 4
  • 寄存器寻址模式与直接寻址模式

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

    我试图了解寄存器必须具备什么标准才能被称为 通用寄存器 我相信通用寄存器是一个可以用于任何用途的寄存器 用于计算 将数据移入 移出等 并且是一个没有特殊用途的寄存器 现在我读到了ESP寄存器是通用寄存器 我猜是ESP寄存器可以用于任何事情
  • 弹出 x86 堆栈以访问函数 arg 时出现分段错误

    我正在尝试链接 x86 程序集和 C 我的C程序 extern int plus 10 int include
  • 如何在 Linux x86_64 上模拟 iret

    我正在编写一个基于 Intel VT 的调试器 由于当 NMI Exiting 1 时 iret 指令在 vmx guest 中的性能发生了变化 所以我应该自己处理vmx主机中的NMI 否则 guest会出现nmi可重入错误 我查了英特尔手
  • “mov (%ebx,%eax,4),%eax”如何工作? [复制]

    这个问题在这里已经有答案了 一直在从事装配作业 并且在很大程度上我对装配非常了解 或者至少对于这项任务来说足够好 但这个 mov 的声明让我很困惑 如果有人能解释这个 mov 语句如何操作寄存器值 我将非常感激 mov ebx eax 4
  • 程序集比较标志理解

    我正在努力理解汇编程序中的以下代码片段 if EAX gt 5 EBX 1 else EBX 2 在汇编程序中 可以写如下 根据我的书 模拟jge操作说明 https www felixcloutier com x86 jcc您通常会使用
  • 如何将 x86 GCC 风格的 C 内联汇编转换为 Rust 内联汇编?

    我在 C 中有以下内联汇编 unsigned long long result asm volatile byte 15 byte 49 shlq 32 rdx orq rdx rax a result rdx return result
  • 如何使用movntdqa避免缓存污染?

    我正在尝试编写一个 memcpy 函数 该函数不会将源内存加载到 CPU 缓存中 目的是避免缓存污染 下面的 memcpy 函数可以工作 但会像标准 memcpy 一样污染缓存 我正在使用带有 Visual C 2008 Express 的
  • MikeOS 引导加载程序中的堆栈段

    我不明白这段代码 mov ax 07C0h Set up 4K of stack space above buffer add ax 544 8k buffer 512 paragraphs 32 paragraphs loader cli
  • 如何在程序中将自己缝合到自己的尾部,无限循环地封装 64KB 代码段?

    如果指令的顺序执行经过偏移量 65535 则8086将从同一代码段中的偏移量 0 处获取下一个指令字节 接下来的 COM 程序利用这一事实 不断将其整个代码 总共 32 个字节 缝合到自己的尾部 环绕在 64KB 代码段中 你可以称之为二元
  • 为什么 clang 使用 -O0 生成低效的 asm(对于这个简单的浮点和)?

    我正在 llvm clang Apple LLVM 版本 8 0 0 clang 800 0 42 1 上反汇编此代码 int main float a 0 151234 float b 0 2 float c a b printf f c
  • 为什么我的代码显示垃圾?

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

随机推荐

  • 使用参数从 Cocoa App 执行 Applescript

    我想知道如何从可可应用程序传递参数执行 applescript 我已经在 stackoverflow 的其他问题中看到了执行不带参数的 applescripts 是多么容易 但是使用 NSAppleScript 类 其中我没有看到任何方法可
  • src 文件夹中的 Toolkit.getImage()

    我试图从包中的 src 文件夹中获取图像 但是没有成功 nekoPics i tk getImage getClass getResource String format resources pracs neko s nekosrc i 有
  • 调用 list.remove(0) 时出现奇怪的 UnsupportedOperationException

    我有这个方法 它接受字符串的可变参数 从中创建一个列表 然后尝试删除列表的第一个元素 public void importFrom String files List
  • 如何在Python中检查一个数字是否有下标?

    我有一个字符串 如下所示 t 这使我的代码失效 int t 出现错误 ValueError invalid literal for int with base 10 如何检测字符串是否是上标而不是实整数 我只想将字符串数字转换为 int 并
  • 应用程序调用了为不同线程编组的接口 - Windows 应用商店应用程序

    所以 首先我已经阅读了大量关于这个特定问题的帖子 但我仍然不明白如何解决它 基本上 我试图与 websocket 进行通信 并将收到的消息存储在绑定到列表视图的可观察集合中 我知道我从套接字正确地得到了响应 但是当它尝试将其添加到可观察集合
  • Firebase Auth 链接提供商 Google 登录问题?

    第一次 在使用 Gmail 和密码注册时 firebase 正确保存了凭据 但下一次 我使用 Firebase Google 身份验证 使用注册时提供的相同 Gmail 进行登录 时 凭据将在 Firebase 帐户中被覆盖 覆盖凭据后 我
  • android 的 eclipse 错误:id 无法解析或不是字段

    我刚刚开始玩android开发 并且已经尝试制作一个按钮 我遇到了一个问题 我在以下代码中给出的错误就在 R id button1 上 它说 id 无法解析或不是一个字段 我是否需要手动引用在布局 xml 文件中创建的每个对象 我发现这确实
  • 在 Spring Boot 应用程序中创建自定义连接池

    我正在编写一个 Spring Boot 应用程序 它与 Snowflake 数据仓库连接并对其执行 SQL 查询 我编写了一个配置类来配置数据源以连接到雪花数据仓库 如下所示 Configuration EnableAutoConfigur
  • 如何让 flutter run -d chrome 使用 https?

    我一直在使用flutter run d chrome启动我的应用程序的网络版本 该应用程序使用 FirebaseAuth 当我尝试使用 Google 登录时 它告诉我它不安全 我认为因为run命令正在为 http 请求而不是 https 设
  • 将自定义工具添加到 android adb shell

    理想情况下 这个问题的答案应该是无根的 我正在考虑重写 adb 工具之一 sendevent c 我在网上找到了这个文件 并且相信我可以根据我的目的对其进行调整 我想我可以将我的新文件推送到设备 但我不确定的是我可以放置该文件的目录以便它可
  • jQuery/javascript - 输入字段(用户、密码)就像 Twitter 的登录一样?

    我怎样才能达到像twitter一样的效果登录表单 右上角 当您单击用户名 传递时 值 用户名 会保留在那里 直到您输入文本 而且也有点暗淡 谢谢你 我已经编写了一个插件来执行此操作 但找不到任何使用类似 twitter div 默认值的插件
  • 将点云的坐标转换为点云库中的另一个坐标,从而使地平面成为X-O-Y平面?

    我有一个来自 kinect fusion 的点云 并使用点云库来分割地平面 ax by c z d 0 成功 我在地平面的 pcl ModelCoefficients 中得到了 a b c d 现在我需要将笛卡尔坐标转换为新的笛卡尔坐标 使
  • 当 iOS 应用程序在后台运行时,您可以收听 Firestore 更新吗?

    我对 Firestore 非常陌生 并试图了解实时更新的工作原理 我现在使用类似的方法从 Firestore 获取更新 db collection Collections session whereField participants ar
  • Linq - 检查where子句中的条件如果字段可以为空

    我有问题 即使项目没有引用 如何检查 where 子句中的条件 最基本的方法 我正在检查我的类中的字段 该字段可以为空 当我以这种方式检查它时 它将返回空引用异常 var soldOutProducts from p in list whe
  • swing 未捕获的异常处理程序

    我正在尝试为 swing 应用程序构建一个通用异常处理程序 如下所述 http www javaspecialists eu archive Issue081 html 我在 jython 中工作 python 语法被编译为 java 并执
  • 我想在Android中使用Xpath来解析XML

    我喜欢在java中使用Xpath解析XML 但是当我在android上做同样的事情时 找不到XPath 任何想法如何实施 如果不可能的话 还有其他更快的 Android 解析器吗 Thanks Kai Android XPath 自 And
  • 获取外键值

    如何获取外键值 我有一个常见的车辆模型 它链接到年份 系列 发动机类型 车身样式 变速箱和传动系统 全部作为外键 我想获取我的应用程序的这些字段的值 但我不知道如何处理它们 任何想法都将受到高度赞赏 class Model models M
  • 完美滚动条默认滚动条保留,并且“完美滚动条”不起作用

    我真的需要这方面的帮助 我想用 完美滚动条 替换 iframe 上的默认滚动条 我已经下载了完美的滚动条 我还将所需的文件包含到我的 html 文档中 根据文档 我在 iframe 中设置了内容容器的样式 结果是 当我加载主页并将鼠标光标移
  • 如何在 1 次后停止 gif 反应本机?

    我有一个 gif 正在反应 我想停止循环 我在我的视图中添加了一个图像 我给图像提供了我的 gif 的路径 它可以工作 但是 gif 进入无限循环 有什么办法停下来吗
  • 如何使用 AVR 的 gnu 汇编器相对于 PC 跳转?

    我有一个使用 avr objcopy 反汇编的二进制文件 中断向量表如下所示 00000000 VECTOR TABLE 0 13 c0 rjmp 38 0x28 RESET 2 b8 c1 rjmp 880 0x374 INT0 4 fd