开发者

Specifying array in Assembler

I wanna specify a 512 x 32 bit array in my assembly file and this looks as follows:

#define FUNCTION_01     test
#define LABEL_01(name)  .L ## test ## _ ## name

  .section ".data"
  my_array:
  .word 0x10101010
  .word 0x20101010
  .word 0x30101010
  .word 0x40101010
  ...

    .section ".text"
    .align 4
    .global FUNCTION_01
    .type   FUNCTION_01,#function

FUNCTION_01:

  add  %g0, 12, %l7           
  ld   [%l7 + my_array], %l7
  ...      
    ret
    restore

    LABEL_01(end):
    .size    FUNCTION_01,LABEL_01(end)-FUNCTION 

So what I try to do in function_01 is to access the 4-th element in my array. However, when I try to compile the assembly above for the SPARC architecture I get the following error:

(.text+0x75开发者_运维知识库c): relocation truncated to fit: R_SPARC_13 against `.data'
collect2: ld returned 1 exit status

Not sure what to make from this error. Does it mean the array is to big or did I something else wrong in the code?


WARNING: I have never used sparc assembly, but seeing as no one has answered yet, I did a quick tutorial to see if I could help.

According to this page, the constant in the ld instruction must be an offset within 4KiB of the current value. You are trying to add an address, not an offset, which is why you get the error. Also, it is possible that the data section will be more than 4 KiB away from the text section. What you need to do is put the address of the array in %l7 and use the 12 bytes as the constant to ld. To do this, you can use the set instruction (This is not actually an instruction, the assembler changes it to a sethi and or combination.).

set  my_array,%l7
ld   [%l7 + 12],%l7


The ld [%l7 + my_array], %l7 instruction is assembled into a 32-bit opcode, which contains (among other things) a 13-bit field for the my_array value (i.e. the array address). The error message is the linker telling you that it has trouble fitting a 32-bit address into a 13-bit field...

To load a 32-bit address into a register, you have to use two instructions, namely sethi (which sets the upper 22 bits) and or (to set the lower 10 bits). This would look like this:

sethi  %hi(my_array), %l7
or     %l7, %lo(my_array), %l7
ld     [%l7+12], %l7

which accesses the fourth array element. The first two instructions can be replaced with the pseudo-instruction set:

set    my_array, %l7
ld     [%l7+12], %l7

which yields the same machine code. Either way, the assembler produces a sethi opcode with a 22-bit field, and an or opcode with a 10-bit data field, and writes into the object file metadata the locations of those opcodes. The linker, who gets all object files and decides where the my_array array will finally go in RAM, fills those fields. Note: if you intend to place your code in a shared library (a .so file), then things are more complex.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜