【问题标题】:Raspberry Pi 3 Model B ARM assembly Illegal Instruction (Core Dumped)Raspberry Pi 3 Model B ARM 组装非法指令(核心转储)
【发布时间】:2018-02-22 01:16:42
【问题描述】:

我正在搞乱我的新树莓派,而且我对组装还很陌生。我已经在 Google 和 SO 上寻找解决方案,这是我最接近运行程序的方法。

main.s(cmets 来自我在互联网上找到的解释)

.section .text
.global _start

_start:
    mov x0, #0 // return value 0 for success
    mov x7, #1 // 1 is exit in the vector table
    svc 0      // execute the system call to exit the program

然后我与as main.s -o main.o 组装并与ld main.o -o main 链接。使用./main 运行输出“非法指令(核心转储)”。

这是在 64 位四核 ARM Cortex-A53 上运行 ARM Arch Linux 的 Raspberry Pi Model B。

目标:编译并链接只有 asld 的 ARM 汇编程序将成功退出

【问题讨论】:

  • 尝试将此添加到顶部.section .text
  • @user8908459 结果相同 :(
  • 有机会仔细看看这个。您正在将值 0 移动到内存地址 0。您不能只写入任意内存位置。该程序失败,因为它试图写入它不拥有的内存区域。尝试将其移至有效寄存器。 mov r1, #0
  • 使用strace ./main 来跟踪系统调用。在svc 0 以失败返回而不是退出后它可能会出现故障(因此执行落入下一步)。但是 IDK AArch64 系统调用 ABI 所以 IDK 如果svc 0 甚至是正确的指令。我认为它适用于 32 位 ARM。
  • @PeterCordes 你刚刚拯救了这一天。我读了man syscall。结果是在 arm64 上,您将参数放入 x8,我正在随机谷歌搜索,发现 github.com/seccomp/libseccomp/blob/master/src/…random github 在“退出”数字 93 下。我会将解决方案放在未来的傻瓜的问题中。再次感谢您的智慧。

标签: assembly raspberry-pi raspberry-pi3 arm64 archlinux-arm


【解决方案1】:

syscall 的手册页中,它指出系统调用的 arm64 架构调用约定是:“argument: x8”和“instruction: svc #0”。在this github project 上,“exit”的系统调用参数定义为“93”。因此,这是一个仅使用 asld 编译的工作、退出和后续的 arm 程序...

.section .text
.global _start

_start:
    mov x0, #0  // exit with status 0
    mov x8, #93 // svc argument goes in x8, and the argument for 'exit' is 93
    svc #0      // executes a syscall in arm64

Another answer 在 SO 上提供有关系统调用的有用信息

【讨论】:

  • x0 也是系统调用的第一个参数。现在,您正在进行sys_exit(x0) 系统调用,其中x0 设置为_start 开头的任何值。 Linux(内核)在启动新进程之前将寄存器归零,但如果您动态链接您的进程,动态链接器可能会将其保留为非零。
  • @PeterCordes 你说的太对了,我改了
【解决方案2】:

您正在将值 0 移动到内存地址 0。您不能只写入任意内存位置。该程序失败,因为它试图写入它不拥有的内存区域。尝试将其移至有效寄存器。

还有很多不错的教程:

https://azeria-labs.com/writing-arm-assembly-part-1/

http://www.peter-cockerell.net/aalp/html/frames.html

https://www.coranac.com/tonc/text/asm.htm

还有视频:

https://www.youtube.com/watch?v=Sm6v9UyhCkA

【讨论】:

  • 我将其更改为 x0,因为每次我使用 r0,as 都会给我Error: operand 1 must be an integer register -- `mov r1,#0`。我确定这与问题有关。这会像as 配置问题,还是我缺少 Arch Linux 的某些东西?
  • 使用 gdb 时,它会进入 svc 行并显示“0x00000000000400084 in ?? ()”和“找不到当前函数的边界”
  • @ibstevieb123:AArch64 没有r1 寄存器。 32 位寄存器命名为w1,64 位寄存器命名为x1。这个答案是错误的。在这些说明中我没有看到存储到内存。
  • @ibstevieb123:在 GDB 中使用layout reg 获得一个反汇编窗口,该窗口围绕当前指令指针进行反汇编。
  • @PeterCordes 哇!我不知道那是一回事。我做到了,看起来当它执行svc 指令时,它输出“0x0400084 in ?? ()”,然后它只是移动到一个(垃圾)指令,该指令产生“找不到当前函数的边界” .我想它会继续这样做,直到它超出程序的范围,导致处理器异常产生“非法指令(核心转储)”。哇。非常感谢你向我展示了这一点。
【解决方案3】:
.section .text
.global _start

_start:
    //mov r0, #0 // ARM 32-bit version
    mov x0, #0   // ARM 64-bit version
    //mov r7, #1 // ARM 32-bit version of this (Raspbian)
    mov x8, #93  // ARM 64-bit version of this (Ubuntu 64-bit, Arch64)
    svc 0        // execute the system call to exit the program

【讨论】:

  • 欢迎来到 SO!当你只用代码回答问题时,试着稍微描述一下。
  • 与公认的答案相比,唯一增加的是 Raspbian 使用 32 位模式这一事实。
猜你喜欢
  • 2018-11-13
  • 2017-01-15
  • 2018-12-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-09-13
  • 2021-09-06
相关资源
最近更新 更多