我正在使用GCC选项// PersonMapper.java
public class PersonMapper implements ResultSetMapper<Person> {
public Person map(int index, ResultSet r, StatementContext ctx) throws SQLException {
Person person = new Person();
person.setId(r.getInt("id"));
person.setName(r.getString("name"));
return person;
}
}
和-mpic-data-is-text-relative
来生成与位置无关的代码。这适用于我的C代码。
但我也有需要使用PIC的汇编代码。问题是我找不到如何实现这个的例子。是否有一些ARM GCC程序集关键字,我是否需要设置自己的GOT表或是否有任何巧妙的技巧?
我正在尝试使用PIC从代码中获取变量:
-fpic
如上所述,在 .section .data @HWA_SWI_HND_DATA, "w"
hwa_ext_reset_hnd:
.word 0x00000000
.section .text @HWA_SWI_HND_CODE, "x"
.code 32
.list
.global hwa_reset_cb_attach
hwa_reset_cb_attach:
ldr r1, =hwa_ext_reset_hnd
str r0, [r1]
bx lr
调用中,我希望此地址获取为PIC。
答案 0 :(得分:1)
Elf DATA遵循文本,并且可以在链接时知道数据的偏移量。您需要将PC添加到已知位置和数据之间的偏移量以访问数据。请参阅ARM ELF和Linkers and loader chp8 by John Levine。
显然,如果它由操作系统和加载程序托管,则需要使用平台的约定。以下内容是为裸机系统或您可以选择的地方编写的。
例如,
.global hwa_reset_cb_attach
hwa_reset_cb_attach:
adr r2, 1f ; pc relative value of label '1'
ldr r1, [r2] ; offset between label and data to r1
add r1, r1, r2 ; pc + offset
str r0, [r1] ; store to corrected address.
bx lr
1: .word hwa_ext_reset_hnd-. ; offset from here to data fixed at link.
这适用于PIC代码,后面有数据。如果您有多次出现,可以创建一个宏来访问数据。如果有很多引用,可能更容易保持寄存器加载 .data 部分的开头。带有编译器选项-msingle-pic-base
和-mpic-register=
reg 的静态基础; 静态基础通常为r9
。因此,数据的加载时间开始时间为r9
一次,仅使用str rx,[r9, #hwa_ext_reset-start_of_data]
。这是 u-boot 使用的策略,您甚至可以重新定位数据部分(从iram移动到SDRAM等)。但是,它会消耗额外的寄存器。
答案 1 :(得分:1)
如果裸机系统上的.text
部分是可写的,最简单的方法是将变量移动到.text
部分。然后,您可以使用LDR / STR / ADR直接使用PC相对寻址访问数据:
.section .text @HWA_SWI_HND_CODE, "xw"
.code 32
hwa_ext_reset_hnd:
.word 0x00000000
.global hwa_reset_cb_attach
hwa_reset_cb_attach:
str r0, hwa_ext_reset_hnd
bx lr
请注意,hwa_ext_reset_hnd
不仅必须在同一部分中定义,还需要在同一个程序集文件中定义,以便汇编程序可以计算出PC的相对偏移量。
如果您的文本部分不可写,那么您仍然可以使用PC相对寻址来完成这些事情:
hwa_reset_cb_attach:
ldr r1, _offset_hwa_ext_reset_hnd
_base_hwa_ext_reset_hnd:
str r0, [pc, r1]
bx lr
_offset_hwa_ext_reset_hnd:
.word hwa_ext_reset_hnd - (_base_hwa_ext_reset_hnd + 8)