Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to use 32-bit w registers in ARM aarch64 GCC inline assembly?

I can use 64-bit registers for example as in:

#include <assert.h>
#include <inttypes.h>

int main(void) {
    uint64_t io = 1;
    __asm__ (
        "add %[io], %[io], 1;"
        : [io] "+r" (io)
        :
        :
    );
    assert(io == 2);
}

which compiles and disassembles with:

aarch64-linux-gnu-gcc -ggdb3 -o main.out main.c
gdb-multiarch -batch -ex 'disassemble/rs main' main.out

to a 64-bit register as expected:

6           __asm__ (
   0x0000000000000744 <+16>:    a0 0f 40 f9     ldr     x0, [x29, #24]
   0x0000000000000748 <+20>:    00 04 00 91     add     x0, x0, #0x1
   0x000000000000074c <+24>:    a0 0f 00 f9     str     x0, [x29, #24]

How to use 32-bit registers such as w0 instead?

Tested on Ubuntu 18.04, GCC 7.4.0.

like image 935
Ciro Santilli Avatar asked Oct 23 '25 18:10

Ciro Santilli


1 Answers

It can be done by adding the w in front of the %, e.g.:

#include <assert.h>
#include <inttypes.h>

int main(void) {
    uint32_t io = 1;
    __asm__ (
        "add %w[io], %w[io], 1;"
        : [io] "+r" (io)
        :
        :
    );
    assert(io == 2);
}

which now disassembles to the desired 32-bit version:

6           __asm__ (
   0x0000000000000744 <+16>:    a0 1f 40 b9     ldr     w0, [x29, #28]
   0x0000000000000748 <+20>:    00 04 00 11     add     w0, w0, #0x1
   0x000000000000074c <+24>:    a0 1f 00 b9     str     w0, [x29, #28]

This could have been somewhat guessed from: http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.100067_0612_00_en/qjl1517569411293.html since the ARM compiler 6 is LLVM based, and LLVM syntax is mostly GCC based.

like image 101
Ciro Santilli Avatar answered Oct 27 '25 01:10

Ciro Santilli



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!