如何从 C 源文件调用 arm 程序集?

Posted

技术标签:

【中文标题】如何从 C 源文件调用 arm 程序集?【英文标题】:How to call arm assembly from C source files? 【发布时间】:2015-10-12 12:59:32 【问题描述】:

我找到了许多关于使用 android NDK 编译汇编代码的好教程。但是他们没有关于如何从 C 源文件调用汇编指令的信息,我相信这是可能的。我想我在网上看到过类似的教程。我的问题是我是否可以拥有一个发出汇编调用的 C 源文件。我还希望能够使用 NDK 进行编译。但我喜欢避免使用 Android Studio 和 JNI;一个原因是我没有任何 Java 代码。而且我已经验证我可以使用 NDK 编译和运行 C 源文件。所以基本上我知道如何使用 NDK 编译 C 源文件和汇编文件。我已经验证 C 代码在我的手机上运行良好。但我不确定如何从 C 源文件中为 arm 架构调用汇编指令。当我尝试编译一个简单的源文件时,我不断收到以下错误消息:

/tmp/ccwua4Gd.s: Assembler messages:
/tmp/ccwua4Gd.s:18: Error: selected processor does not support Thumb mode `smc #0'

这是文件:

#include <stdio.h>

__asm__(" smc #0");

int main(void)

  /*Do something*/
  return 0;

顺便说一句,这个问题似乎与拇指与手臂无关。我确实在我的 Android.mk 中尝试了 LOCAL_ARM_MODE := arm 声明,但它没有解决任何问题。我刚刚收到 ARM 指令的类似错误。

更新:我仍然收到该错误。这是我的 Android.mk 的副本 为了在设备上执行,我不必在早期的 C 源文件中指定 arm 版本或 arm/thumb 规范。我已经阅读了有关 thumb 以及与该选项相关的优缺点,以及如何指定对它的支持。然而,即使我配置了 ABI,这个错误仍然存​​在。我没有尝试过的一件事是将 .arm 扩展名添加到我的 C 源文件中。我在较早的帖子中看到了对它的引用,但无法弄清楚为什么会有所作为。我相信该线程中的 OP 暗示这将解决该错误。任何人都可以详细说明吗?有人用过吗?与架构相关的 Android.mk 语句相比,这样做的效果是什么? 谢谢

LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS) 
LOCAL_MODULE := hello  
APP_ABI := armeabi-v7a
FILE_LIST := $(wildcard $(LOCAL_PATH)/*.c)
$(warning here is what is in FILE_LIST after an attempt to collect all the C files$(FILE_LIST))
FILE_LIST += $(wildcard $(LOCAL_PATH)/*.s)
$(warning here is what is in FILE_LIST after an attempt to collect all the S files$(FILE_LIST))
LOCAL_SRC_FILES := $(FILE_LIST:$(LOCAL_PATH)/%=%)
include $(BUILD_EXECUTABLE)

另一个更新 - 我尝试将 .arm 后缀添加到我的 C 源文件中,将 foo.c 更改为 foo.c.arm,但即使这样也没有解决问题。任何帮助是极大的赞赏。这是我现在在我的 Android.mk 文件中所做的:

FILE_LIST := $(patsubst %.c,%.c.arm,$(wildcard $(LOCAL_PATH)/*.c))

这是错误的更新版本。它只是将单词“thumb”更改为“arm”

/tmp/ccTK9siq.s: Assembler messages:
/tmp/ccTK9siq.s:17: Error: selected processor does not support ARM mode `smc #0'

嘿,我做了更多研究,发现this 链接关于我的问题。我按照页面中的说明使用 LOCAL_CFLAGS := -mcpu=cortex-a8 更新了我的 Android.mk 文件。问题并没有消失,但我收到了一条信息性消息:warning: switch -mcpu=cortex-a8 conflicts with -march=armv5te switch [enabled by default] 所以下面建议的命令并没有真正生效。有谁知道我是否应该尝试更改 ndk-build 的默认设置以及如何更改?毕竟这是一个警告;不是错误。所以我不确定它是否需要我的配置或者我需要做其他事情。 此外,现在我收到一个关于丢失唯一头文件 stdio.h 的错误,这是我以前没有得到的。这种告诉我 ndk-build 只是在该警告之后提交了构建过程。任何人都可以为此提供指导或解决方案吗?

073015 更新 - 我意识到 application.mk 和 Android.mk 之间存在差异。使用所述参数配置 applicaiton.mk 后,我能够将架构更改为 armv7-a 但我得到了同样的错误;往下看:

jni/Android.mk:6: This is in NDK_ROOT /home/sansari/android/android-ndk-r10d
[armeabi-v7a] Assembly       : hello_tz <= main_normal.filtered.s
./obj/local/armeabi-v7a/objs-debug/hello_tz/main_normal.filtered.s: Assembler messages:
./obj/local/armeabi-v7a/objs-debug/hello_tz/main_normal.filtered.s:16: Error: **selected processor does not support ARM mode `smc #0'**
make: *** [obj/local/armeabi-v7a/objs-debug/hello_tz/main_normal.o] Error 1

是否需要进行任何其他配置才能获得我想要的功能?

【问题讨论】:

来自infocenter.arm.com/help/topic/com.arm.doc.dui0489c/… >SMC“架构”部分 如果具有安全扩展,则此 ARM 指令可用于 ARMv6 及更高版本的实现。如果 ARMv6T2 及更高版本具有安全扩展,则此 32 位 Thumb 指令可用。该指令没有 16 位 Thumb 版本。 我确实阅读了 SMC 指令的 arm 规范。除了下面提到的拉里之外,我还需要在我的 C 源代码或 Android.mk 中做些什么不同的事情? Toris- 请查看我的最新更新。连 armeabiv7a 都不支持 smc 调用。 【参考方案1】:

问题是您正在注入适用于 ARMv6 或更高版本的程序集。如果您未在 NDK Application.mk 中指定 ABI,则这些工具假定为 ARMv5。

【讨论】:

要指定要构建的 ABI,请在 Application.mk 中设置 APP_ABI(例如 APP_ABI := armeabi-v7a 我改变了架构;但即使 armeabiv7-a 也不支持安全扩展。你能看看我最新的错误信息吗?我是否需要在 Application.mk 或 Android.mk 中配置另一个变量才能得到这个? 不,一般来说,NDK 编译器不打算创建独立的本机应用程序。 Android 期望所有应用程序都在 (java) 运行时环境中运行。因此,编译器可能受限于它支持的扩展类型也就不足为奇了。

以上是关于如何从 C 源文件调用 arm 程序集?的主要内容,如果未能解决你的问题,请参考以下文章

ARM程序集 - bl正在分支到错误的地址

如何在非托管 c++ dll 中查找调用方程序集名称

如何将其转换为 32 位架构 ARM 程序集

如何获取每个GAC程序集的位置?

使用寄存器而不是堆栈从 x64 程序集调用 C 函数

通过ARM程序集实现冒泡排序