3

I'm doing a little project using the Android NDK, and I must insert some asm code for ARM architecture.

Everything apart from the asm works just fine, but the asm code tells me that

Operand 1 should be an integer register

when conpiling simple code like

asm("mov r0, r0");


So, what is the problem? Is my computer trying to compile for x86_64 instead of ARM? If so, how should I change that?

Also, I've tried the x86_64 equivalent arm("mov rax, rax"); but the error is the same.

Garmekain
  • 321
  • 2
  • 9
  • Which ABIs are you building for? – Michael Aug 22 '16 at 16:56
  • 1
    Try `mov x0, x0`. If it doesn't give an error then your problem is that you're using 32-bit ARM assembly language with the 64-bit ARM toolchain. You either need to switch to 32-bit tools or 64-bit assembly language. By the way, you should investigate whether you really need to use inline assembly. It's hard to get right. See if you can't use intrinsics to do what you want instead. – Ross Ridge Aug 22 '16 at 19:16
  • 1
    When targeting x86, the default asm syntax is AT&T style, so `asm("mov %rax, %rax");` should work as a no-op. Use `gcc -S` to generate an asm output file. Look for `#APP` / `#NO_APP` around your code, and see if it looks like the surrounding compiler-generated asm. e.g. https://godbolt.org/g/h8JIEy – Peter Cordes Aug 22 '16 at 19:44
  • Re: @Ross's last point, see https://gcc.gnu.org/wiki/DontUseInlineAsm. Also see [my answer on this Q&A](http://stackoverflow.com/questions/38035351/rgba-to-abgr-inline-arm-neon-asm-for-ios-xcode) for an example of how easy it is to get it wrong, and a stubborn OP that refuses to believe his asm is unsafe because it happens to work with his current surrounding code. – Peter Cordes Aug 22 '16 at 19:47
  • @RossRidge If I put `mov x0, x0` it says _too many memory references for `mov'_ – Garmekain Aug 23 '16 at 10:44

1 Answers1

2

All your C sources are compiled for each architecture that is mentioned in your APP_ABI. So there is no point wondering why ARM assembly was not understood by x64 compiler or vice versa.

Do not use inline assembly. It is much better to put all assembly stuff into dedicated *.S sources, that will be processed by as (NDK toolchains have it). Those assembly sources should be placed into appropriate folders like arch-arm/, arch-x86/. Then you should add them to Android.mk properly:

LOCAL_SRC_FILES := arch-$(TARGET_ARCH)/my_awesome_code.S

$(TARGET_ARCH) helps to resolve path to appropriate source in a correct and painless way.

P.S. Also standalone assembly gives more abilities to you than inline. This is one more reason to avoid using inline assembly. Moreover inline assembly syntax differs from compiler to compiler since it is not part of any standard.

hippietrail
  • 15,848
  • 18
  • 99
  • 158
Sergio
  • 8,099
  • 2
  • 26
  • 52
  • Even doing that, having ` .text .global MyAsmFunction .type MyAsmFunction function MyAsmFunction: mov x0,#2` as my `.s` file, doing what you said and having `extern "C" void MyAsmFunction();` It outputs the error _expecting operand after ','; got nothing_, which is one of the error I got in inline asm. – Garmekain Aug 23 '16 at 12:09