- iOS/Objective-C 元类和类别
- objective-c - -1001 错误,当 NSURLSession 通过 httpproxy 和/etc/hosts
- java - 使用网络类获取 url 地址
- ios - 推送通知中不播放声音
我最近在使用 Assembly 编程时遇到了 ARM Cortex-A8 的一个奇怪行为。每当我 MOV
任何东西到 R4 时,我的程序就会崩溃(下面的堆栈转储)
10-14 09:48:43.117: INFO/DEBUG(3048): Build fingerprint: 'google/soju/crespo:2.3.6/GRK39F/189904:user/release-keys'
10-14 09:48:43.121: INFO/DEBUG(3048): pid: 7082, tid: 7082 >>> neontests <<<
10-14 09:48:43.121: INFO/DEBUG(3048): signal 11 (SIGSEGV), code 1 (SEGV_MAPERR), fault addr 00000001
10-14 09:48:43.125: INFO/DEBUG(3048): r0 00000001 r1 afa025b6 r2 00000000 r3 bec77051
10-14 09:48:43.128: INFO/DEBUG(3048): r4 00000001 r5 bec7704c r6 00000001 r7 00000004
10-14 09:48:43.128: INFO/DEBUG(3048): r8 00000005 r9 00000000 10 4214cca4 fp 800a5368
10-14 09:48:43.128: INFO/DEBUG(3048): ip afa03110 sp bec77010 lr afa0133b pc afd37b42 cpsr 60000030
10-14 09:48:43.132: INFO/DEBUG(3048): d0 0000000200000053 d1 0000000400000074
10-14 09:48:43.132: INFO/DEBUG(3048): d2 000000060000006f d3 0000000800000070
10-14 09:48:43.132: INFO/DEBUG(3048): d4 006f0065006e002e d5 007300650074006e
10-14 09:48:43.136: INFO/DEBUG(3048): d6 0000000c00000005 d7 0000002000000015
10-14 09:48:43.136: INFO/DEBUG(3048): d8 0000000c00000005 d9 0000002000000015
10-14 09:48:43.140: INFO/DEBUG(3048): d10 0000000000000000 d11 0000000000000000
10-14 09:48:43.140: INFO/DEBUG(3048): d12 0000000000000000 d13 0000000000000000
10-14 09:48:43.140: INFO/DEBUG(3048): d14 0000000000000000 d15 0000000000000000
10-14 09:48:43.144: INFO/DEBUG(3048): d16 800220e8401644a8 d17 bff0000000000000
10-14 09:48:43.144: INFO/DEBUG(3048): d18 3ff0000000000000 d19 0000000000000000
10-14 09:48:43.148: INFO/DEBUG(3048): d20 0000000000000000 d21 0000000000000000
10-14 09:48:43.148: INFO/DEBUG(3048): d22 3ff0000000000000 d23 0000000000000000
10-14 09:48:43.148: INFO/DEBUG(3048): d24 3ff0000000000000 d25 0000000000000000
10-14 09:48:43.148: INFO/DEBUG(3048): d26 0000000000000000 d27 0000000000000000
10-14 09:48:43.148: INFO/DEBUG(3048): d28 0000000000000000 d29 0000000000000000
10-14 09:48:43.148: INFO/DEBUG(3048): d30 0000000000000000 d31 0000000000000000
10-14 09:48:43.148: INFO/DEBUG(3048): scr 20000012
10-14 09:48:43.195: INFO/DEBUG(3048): #00 pc 00037b42 /system/lib/libc.so
10-14 09:48:43.195: INFO/DEBUG(3048): #01 pc 00001338 /system/lib/liblog.so
10-14 09:48:43.199: INFO/DEBUG(3048): #02 pc 00001482 /system/lib/liblog.so
10-14 09:48:43.199: INFO/DEBUG(3048): #03 pc 00000c54 /data/data/neontests/lib/libneon_tests.so
10-14 09:48:43.199: INFO/DEBUG(3048): #04 pc 00017e34 /system/lib/libdvm.so
10-14 09:48:43.199: INFO/DEBUG(3048): #05 pc 0004968c /system/lib/libdvm.so
10-14 09:48:43.199: INFO/DEBUG(3048): #06 pc 0004ee62 /system/lib/libdvm.so
10-14 09:48:43.199: INFO/DEBUG(3048): #07 pc 0001d034 /system/lib/libdvm.so
10-14 09:48:43.199: INFO/DEBUG(3048): #08 pc 000220e4 /system/lib/libdvm.so
10-14 09:48:43.199: INFO/DEBUG(3048): #09 pc 00020fdc /system/lib/libdvm.so
10-14 09:48:43.199: INFO/DEBUG(3048): #10 pc 0005fdde /system/lib/libdvm.so
10-14 09:48:43.203: INFO/DEBUG(3048): #11 pc 00067b52 /system/lib/libdvm.so
10-14 09:48:43.203: INFO/DEBUG(3048): #12 pc 0001d034 /system/lib/libdvm.so
10-14 09:48:43.203: INFO/DEBUG(3048): #13 pc 000220e4 /system/lib/libdvm.so
10-14 09:48:43.203: INFO/DEBUG(3048): #14 pc 00020fdc /system/lib/libdvm.so
10-14 09:48:43.203: INFO/DEBUG(3048): #15 pc 0005fc40 /system/lib/libdvm.so
10-14 09:48:43.203: INFO/DEBUG(3048): #16 pc 0004c126 /system/lib/libdvm.so
10-14 09:48:43.203: INFO/DEBUG(3048): #17 pc 00032572 /system/lib/libandroid_runtime.so
10-14 09:48:43.203: INFO/DEBUG(3048): #18 pc 0003341e /system/lib/libandroid_runtime.so
10-14 09:48:43.203: INFO/DEBUG(3048): #19 pc 00008cca /system/bin/app_process
10-14 09:48:43.207: INFO/DEBUG(3048): #20 pc 00014b52 /system/lib/libc.so
10-14 09:48:43.207: INFO/DEBUG(3048): code around pc:
10-14 09:48:43.207: INFO/DEBUG(3048): afd37b20 18801889 c003f810 c003f801 d2f93b01
10-14 09:48:43.207: INFO/DEBUG(3048): afd37b30 bf00bdf0 2200b510 3201e003 4618b90b
10-14 09:48:43.207: INFO/DEBUG(3048): afd37b40 5c83e004 42a35c8c 1b18d0f7 bf00bd10
10-14 09:48:43.207: INFO/DEBUG(3048): afd37b50 b152b530 5cc42300 42ac5ccd 1b60d001
10-14 09:48:43.207: INFO/DEBUG(3048): afd37b60 b114e004 429a3301 2000d1f5 bf00bd30
10-14 09:48:43.207: INFO/DEBUG(3048): code around lr:
10-14 09:48:43.207: INFO/DEBUG(3048): afa01318 fffffff4 00001e20 b088b570 4615460c
10-14 09:48:43.207: INFO/DEBUG(3048): afa01328 b9099001 447c4c28 46204928 f7ff4479
10-14 09:48:43.207: INFO/DEBUG(3048): afa01338 2800edc4 4926d02e 22034620 f7ff4479
10-14 09:48:43.207: INFO/DEBUG(3048): afa01348 b338edc2 46204923 f7ff4479 b308edb6
10-14 09:48:43.207: INFO/DEBUG(3048): afa01358 46204921 f7ff4479 b1d8edb0 4620491f
10-14 09:48:43.207: INFO/DEBUG(3048): stack:
10-14 09:48:43.207: INFO/DEBUG(3048): bec76fd0 800a5368
10-14 09:48:43.207: INFO/DEBUG(3048): bec76fd4 afd1c701 /system/lib/libc.so
10-14 09:48:43.207: INFO/DEBUG(3048): bec76fd8 bec771f0
10-14 09:48:43.207: INFO/DEBUG(3048): bec76fdc bec77051
10-14 09:48:43.207: INFO/DEBUG(3048): bec76fe0 0000ce60
10-14 09:48:43.207: INFO/DEBUG(3048): bec76fe4 000003fa
10-14 09:48:43.207: INFO/DEBUG(3048): bec76fe8 ffff0208
10-14 09:48:43.207: INFO/DEBUG(3048): bec76fec bec7704c
10-14 09:48:43.207: INFO/DEBUG(3048): bec76ff0 000003ff
10-14 09:48:43.207: INFO/DEBUG(3048): bec76ff4 00000000
10-14 09:48:43.210: INFO/DEBUG(3048): bec76ff8 00000003
10-14 09:48:43.210: INFO/DEBUG(3048): bec76ffc 00000004
10-14 09:48:43.210: INFO/DEBUG(3048): bec77000 80400d90 /data/data/neontests/lib/libneon_tests.so
10-14 09:48:43.210: INFO/DEBUG(3048): bec77004 bec7704c
10-14 09:48:43.210: INFO/DEBUG(3048): bec77008 df002777
10-14 09:48:43.210: INFO/DEBUG(3048): bec7700c e3a070ad
10-14 09:48:43.210: INFO/DEBUG(3048): #00 bec77010 00000001
10-14 09:48:43.210: INFO/DEBUG(3048): bec77014 afa0133b /system/lib/liblog.so
10-14 09:48:43.210: INFO/DEBUG(3048): #01 bec77018 80400420 /data/data/neontests/lib/libneon_tests.so
10-14 09:48:43.210: INFO/DEBUG(3048): bec7701c 00000004
10-14 09:48:43.210: INFO/DEBUG(3048): bec77020 bec7701c
10-14 09:48:43.210: INFO/DEBUG(3048): bec77024 00000001
10-14 09:48:43.210: INFO/DEBUG(3048): bec77028 80400d90 /data/data/neontests/lib/libneon_tests.so
10-14 09:48:43.210: INFO/DEBUG(3048): bec7702c 00000014
10-14 09:48:43.210: INFO/DEBUG(3048): bec77030 00000000
10-14 09:48:43.210: INFO/DEBUG(3048): bec77034 00000000
10-14 09:48:43.210: INFO/DEBUG(3048): bec77038 bec7704c
10-14 09:48:43.210: INFO/DEBUG(3048): bec7703c afd4d5c8
10-14 09:48:43.210: INFO/DEBUG(3048): bec77040 00000001
10-14 09:48:43.210: INFO/DEBUG(3048): bec77044 afa01487 /system/lib/liblog.so
编辑:上面的堆栈转储是以下代码的结果(抱歉,GNU 程序集高亮显示在这里似乎有点奇怪):
.arm
.global asm_test
asm_test:
mov r0, #4 @make sure r0 is not the same as r4
mov r4, #1 @move to r4 something different from r0
mov pc, lr @return from function
我从( native )C 调用它如下:
#include <jni.h>
#include <string.h>
#include <stdint.h>
#include <stdlib.h>
#include <arm_neon.h>
#include <android/log.h>
#include "com_something_neontests_NativeLib.h"
extern volatile int asm_test(void);
JNIEXPORT jint JNICALL Java_com_something_neontests_NativeLib_asmTry
(JNIEnv * env, jobject obj)
{
__android_log_print(ANDROID_LOG_INFO, "com.something.neontests", "Start!");
asm_test();
__android_log_print(ANDROID_LOG_INFO, "com.something.neontests", "Done!");
return 0;
}
以下是我注意到的一些事情。首先,每当我为 R4 赋值时,无论是 MOV R4, #2
还是 ADD R4, R0, R1
,结果 确实在程序崩溃之前在 R4 中,但同样的结果也总是在 R0 中结束。我还发现我可以从堆栈中POP
东西到 R4 中。没有其他寄存器表现出同样的行为。汇编代码使用 Android NDK 编译,我相信它使用 GCC 4.4.3。我在几部 Android 手机上对其进行了测试,一切似乎都是一致的。
我知道所有寄存器都是这样划分的,R0-R3 接受参数,R4-R12 是变量寄存器,然后是特殊寄存器等等。也许这种行为是由某种我从未听说过的 C 调用约定引起的?是否对此有解释,是否符合预期?
干杯! =)
更新:
正如@Graham 善意指出的那样,r4(或者v1)是一个应该保留的变量寄存器。然而,在 link在他的回答中提供,ARM 文档本身使用 v1 寄存器,首先将其结果与另一个保留寄存器的值一起保存在堆栈中:
STMDB sp!,{v1,lr}
LDR v1,[a2,#0]
然后检索它们的值。当我编译这段代码时,它会像我原来的那样崩溃,但是
STMDB sp!,{v1,lr}
LDR v2,[a2,#0]
不会(注意 v2 而不是 v1)。
最佳答案
我们试图解释的是,如果你想在函数中使用 r4,你需要这样做:
.globl asm_test
asm_test:
stmdb r13!,{r4}
mov r0, #4 @make sure r0 is not the same as r4
mov r4, #1 @move to r4 something different from r0
ldmia r13!,{r4}
mov pc, lr @return from function
否则你会留下一颗定时炸弹,它会在路上的某个时刻爆炸。编译器已经为更高级函数中的某些东西分配了 r4,并且根据规则,没有人可以更改该寄存器,以便更高级别的调用不必保护 r4,通过在正确的时间和位置搞砸它来创建问题,如何问题的行为取决于代码。并将解释为什么其他寄存器在这种情况下不敏感。有时,当您执行此操作时,您实际上不会崩溃,有时可能字符串打印错误或循环重复或提前退出。
要查看发生了什么,请反汇编有问题的函数(不是源代码,而是反汇编)。加上调用它的函数和调用它的函数,直到 r4 出现在其中一个周围的函数中。检查 r4 的用途。
如果您的 asm_test() 调用函数具有在 asm_test() 调用之前和之后使用的局部变量,您也可以更改行为,优化器将它们保存在寄存器中,同时优化器不会一起删除代码:
void fun ( void )
{
int r;
r=10;
asm_test();
r++;
}
优化器会完全删除上面代码中的 r,但是:
int fun ( int a, int b, int c, int d )
{
int e;
e=a+b+c+d;
b=asm_test(a+d);
e+=b;
return(e);
}
创建的内容足以强制编译器构建堆栈框架。
00000000 <fun>:
0: e0811000 add r1, r1, r0
4: e92d4010 push {r4, lr}
8: e0830000 add r0, r3, r0
c: e0814002 add r4, r1, r2
10: e0844003 add r4, r4, r3
14: ebfffffe bl 0 <asm_test>
18: e0840000 add r0, r4, r0
1c: e8bd8010 pop {r4, pc}
r4 是本例中的变量 e(围绕 asm_test 调用),通过弄乱 r4,您将更改函数 fun() 返回的内容。例如,如果该值从未在调用 fun 时使用过,那么您对 r4 的修改将不会被注意到。
编译器遵循调用约定规则并期望所有被调用者也遵守,如果你搞砸了它崩溃/失败的方式从没有影响到非常严重,所以你需要遵守你的那些调用约定汇编。
关于android - 无法写入 ARM 寄存器 R4 : feature or bug?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7768812/
我正在从 Stata 迁移到 R(plm 包),以便进行面板模型计量经济学。在 Stata 中,面板模型(例如随机效应)通常报告组内、组间和整体 R 平方。 I have found plm 随机效应
关闭。这个问题不符合Stack Overflow guidelines .它目前不接受答案。 想改进这个问题?将问题更新为 on-topic对于堆栈溢出。 6年前关闭。 Improve this qu
我想要求用户输入整数值列表。用户可以输入单个值或一组多个值,如 1 2 3(spcae 或逗号分隔)然后使用输入的数据进行进一步计算。 我正在使用下面的代码 EXP <- as.integer(rea
当 R 使用分类变量执行回归时,它实际上是虚拟编码。也就是说,省略了一个级别作为基础或引用,并且回归公式包括所有其他级别的虚拟变量。但是,R 选择了哪一个作为引用,以及我如何影响这个选择? 具有四个级
这个问题基本上是我之前问过的问题的延伸:How to only print (adjusted) R-squared of regression model? 我想建立一个线性回归模型来预测具有 15
我在一台安装了多个软件包的 Linux 计算机上安装了 R。现在我正在另一台 Linux 计算机上设置 R。从他们的存储库安装 R 很容易,但我将不得不使用 安装许多包 install.package
我正在阅读 Hadley 的高级 R 编程,当它讨论字符的内存大小时,它说: R has a global string pool. This means that each unique strin
我们可以将 Shiny 代码写在两个单独的文件中,"ui.R"和 "server.R" , 或者我们可以将两个模块写入一个文件 "app.R"并调用函数shinyApp() 这两种方法中的任何一种在性
我正在使用 R 通过 RGP 包进行遗传编程。环境创造了解决问题的功能。我想将这些函数保存在它们自己的 .R 源文件中。我这辈子都想不通怎么办。我尝试过的一种方法是: bf_str = print(b
假设我创建了一个函数“function.r”,在编辑该函数后我必须通过 source('function.r') 重新加载到我的全局环境中。无论如何,每次我进行编辑时,我是否可以避免将其重新加载到我的
例如,test.R 是一个单行文件: $ cat test.R # print('Hello, world!') 我们可以通过Rscript test.R 或R CMD BATCH test.R 来
我知道我可以使用 Rmd 来构建包插图,但想知道是否可以更具体地使用 R Notebooks 来制作包插图。如果是这样,我需要将 R Notebooks 编写为包小插图有什么不同吗?我正在使用最新版本
我正在考虑使用 R 包的共享库进行 R 的站点安装。 多台计算机将访问该库,以便每个人共享相同的设置。 问题是我注意到有时您无法更新包,因为另一个 R 实例正在锁定库。我不能要求每个人都关闭它的 R
我知道如何从命令行启动 R 并执行表达式(例如, R -e 'print("hello")' )或从文件中获取输入(例如, R -f filename.r )。但是,在这两种情况下,R 都会运行文件中
我正在尝试使我当前的项目可重现,因此我正在创建一个主文档(最终是一个 .rmd 文件),用于调用和执行其他几个文档。这样我自己和其他调查员只需要打开和运行一个文件。 当前设置分为三层:主文件、2 个读
关闭。这个问题不符合Stack Overflow guidelines .它目前不接受答案。 想改进这个问题?将问题更新为 on-topic对于堆栈溢出。 5年前关闭。 Improve this qu
我的 R 包中有以下描述文件 Package: blah Title: What the Package Does (one line, title case) Version: 0.0.0.9000
有没有办法更有效地编写以下语句?accel 是一个数据框。 accel[[2]]<- accel[[2]]-weighted.mean(accel[[2]]) accel[[3]]<- accel[[
例如,在尝试安装 R 包时 curl作为 usethis 的依赖项: * installing *source* package ‘curl’ ... ** package ‘curl’ succes
我想将一些软件作为一个包共享,但我的一些脚本似乎并不能很自然地作为函数运行。例如,考虑以下代码块,其中“raw.df”是一个包含离散和连续类型变量的数据框。函数“count.unique”和“squa
我是一名优秀的程序员,十分优秀!