assemblygnu-assemblersuperh

How to change a single bit of an address at assemble time?


Arch is SuperH. I have some variables specified like this:

buffer_address: .long buffer
buffer: .zero 1024 

However, for certain buffer reads, I need to read as cache-through. The way to do that on SuperH is to just OR the memory address with 0x20000000.

I would prefer to do this at assemble time, ie, specify a new variable for the cache-through address:

buffer_address_cache_through: .long buffer !(but ORed with 0x2000000 somehow)

What's the gnu assembler syntax for what I'm trying to do here?


Solution

  • You probably can't, per se (but read to the end).

    In a typical assembler+linker toolchain, the absolute addresses of static objects are computed by the linker, not the assembler. Therefore, any static values that depend on absolute addresses must also be computed by the linker. The assembler communicates this to the linker by means of relocations. The types of available relocations depend on the platform and the object file format, and I don't know about SuperH specifically, but typically they are limited to simple ones that are most commonly used, such as "address of symbol plus constant" or "subtract addresses of two symbols". You can't compute arbitrary arithmetic expressions, and I would guess that bitwise operations are not specifically included.

    However, in this case, presumably the original address of buffer has the bit 0x20000000 unset. So a bitwise OR with 0x20000000 is the same as adding 0x20000000, and so you could use addition instead, which is more likely to work. So try

    buffer_address_cache_through: .long buffer + 0x20000000