Указание массива в Ассемблере - PullRequest
3 голосов
/ 14 марта 2011

Я хочу указать 512 x 32-битный массив в моем файле сборки, и это выглядит следующим образом:

#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 

Так что я пытаюсь сделать в function_01 доступ к 4-му элементу в моем массиве,Однако, когда я пытаюсь скомпилировать сборку выше для архитектуры SPARC, я получаю следующую ошибку:

(.text+0x75c): relocation truncated to fit: R_SPARC_13 against `.data'
collect2: ld returned 1 exit status

Не уверен, что делать с этой ошибкой.Значит ли это, что массив слишком большой или я что-то не так в коде?

Ответы [ 2 ]

2 голосов
/ 14 марта 2011

ВНИМАНИЕ: я никогда не использовал сборку sparc, но, поскольку никто еще не ответил, я сделал краткое руководство, чтобы посмотреть, смогу ли я помочь.константа в инструкции ld должна быть смещением в пределах 4 КБ от текущего значения.Вы пытаетесь добавить адрес, а не смещение, поэтому вы получаете сообщение об ошибке.Кроме того, возможно, что раздел данных будет более 4 КиБ от текстового раздела.Вам нужно поместить адрес массива в% l7 и использовать 12 байтов в качестве константы ld.Для этого вы можете использовать инструкцию set (на самом деле это не инструкция, ассемблер меняет ее на комбинацию sethi и or.).

set  my_array,%l7
ld   [%l7 + 12],%l7
0 голосов
/ 15 марта 2011

Инструкция ld [%l7 + my_array], %l7 собрана в 32-битный код операции, который содержит (среди прочего) 13-битное поле для значения my_array (т.е. адрес массива).Сообщение об ошибке - это компоновщик, сообщающий, что у него проблемы с встраиванием 32-разрядного адреса в 13-разрядное поле ...

Для загрузки 32-разрядного адреса в регистр необходимо использовать две инструкцииа именно sethi (который устанавливает старшие 22 бита) и or (чтобы установить младшие 10 битов).Это будет выглядеть так:

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

, который обращается к четвертому элементу массива.Первые две инструкции могут быть заменены псевдоинструкцией set:

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

, которая выдает тот же машинный код.В любом случае ассемблер создает код операции sethi с 22-битным полем и код операции or с 10-битным полем данных и записывает в метаданные объектного файла положения этих кодов операций.Компоновщик, который получает все объектные файлы и решает, куда массив my_array будет наконец помещен в ОЗУ, заполняет эти поля.Примечание: если вы намереваетесь поместить свой код в общую библиотеку (файл .so), то все будет сложнее.

...