【问题标题】:Specifying array in Assembler在 Assembler 中指定数组
【发布时间】:2011-03-14 16:26:17
【问题描述】:

我想在我的程序集文件中指定一个 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

不知道如何解决这个错误。这是否意味着数组太大或者我在代码中还有其他错误?

【问题讨论】:

    标签: c assembly sparc


    【解决方案1】:

    警告:我从未使用过 sparc 程序集,但由于还没有人回答,所以我做了一个快速教程,看看是否可以提供帮助。

    根据this pageld指令中的常量必须是当前值4KiB以内的偏移量。您正在尝试添加地址,而不是偏移量,这就是您收到错误的原因。此外,数据部分与文本部分的距离可能超过 4 KiB。您需要做的是将数组的地址放在 %l7 中,并使用 12 个字节作为 ld 的常量。为此,您可以使用set 指令(这实际上不是一条指令,汇编器将其更改为sethior 的组合。)。

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

    【讨论】:

      【解决方案2】:

      ld [%l7 + my_array], %l7 指令被组装成一个 32 位操作码,其中包含(除其他外)my_array 值(即数组地址)的 13 位字段。错误消息是链接器告诉您它无法将 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
      

      产生相同的机器代码。无论哪种方式,汇编器都会生成一个带有 22 位字段的sethi 操作码和一个带有 10 位数据字段的or 操作码,并将这些操作码的位置写入目标文件元数据。链接器获取所有目标文件并决定my_array 数组最终在 RAM 中的位置,填充这些字段。注意:如果您打算将代码放在共享库(.so 文件)中,那么事情会更复杂。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2011-02-01
        • 1970-01-01
        • 2014-01-16
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2013-02-04
        • 1970-01-01
        相关资源
        最近更新 更多