有没有办法让gcc生成%pc
常量的相对地址?即使字符串出现在文本段中,arm-elf-gcc也会生成一个指向数据的常量指针,通过%pc
相对地址加载指针的地址,然后取消引用它.出于各种原因,我需要跳过中间步骤.举个例子,这个简单的功能:
const char * filename(void)
{
static const char _filename[]
__attribute__((section(".text")))
= "logfile";
return _filename;
}
Run Code Online (Sandbox Code Playgroud)
生成(编译时arm-elf-gcc-4.3.2 -nostdlib -c
-O3 -W -Wall logfile.c
):
00000000 <filename>:
0: e59f0000 ldr r0, [pc, #0] ; 8 <filename+0x8>
4: e12fff1e bx lr
8: 0000000c .word 0x0000000c
0000000c <_filename.1175>:
c: 66676f6c .word 0x66676f6c
10: 00656c69 .word 0x00656c69
Run Code Online (Sandbox Code Playgroud)
我原以为它会产生更像的东西:
filename:
add r0, pc, #0
bx lr
_filename.1175:
.ascii "logfile\000"
Run Code Online (Sandbox Code Playgroud)
有问题的代码需要部分独立于位置,因为它将在加载时重新定位到内存中,但也与未编译的代码集成-fPIC
,因此没有全局偏移表.
我目前的工作是调用非内联函数(将通过%pc
相对地址完成)以类似于-fPIC
代码的工作方式从编译位置查找偏移量:
static …
Run Code Online (Sandbox Code Playgroud) [bits 32]
global _start
section .data
str_hello db "HelloWorld", 0xa
str_hello_length db $-str_hello
section .text
_start:
mov ebx, 1 ; stdout file descriptor
mov ecx, str_hello ; pointer to string of characters that will be displayed
mov edx, [str_hello_length] ; count outputs Relative addressing
mov eax, 4 ; sys_write
int 0x80 ; linux kernel system call
mov ebx, 0 ; exit status zero
mov eax, 1 ; sys_exit
int 0x80 ; linux kernel system call
Run Code Online (Sandbox Code Playgroud)
这里的基本要点是我需要将hello字符串的长度传递给linux的sys_write系统调用.现在,我很清楚我可以使用EQU,它会工作正常,但我真的想了解这里发生了什么.
所以,基本上当我使用EQU时,它会加载值,这很好.
str_hello_length equ $-str_hello …
Run Code Online (Sandbox Code Playgroud) 我有一个二进制文件,我使用avr-objcopy进行了反汇编.中断向量表如下所示:
00000000 : ; VECTOR TABLE 0: 13 c0 rjmp .+38 ; 0x28, RESET 2: b8 c1 rjmp .+880 ; 0x374, INT0 4: fd cf rjmp .-6 ; 0x0 6: fc cf rjmp .-8 ; 0x0 8: fb cf rjmp .-10 ; 0x0 a: fa cf rjmp .-12 ; 0x0 c: f9 cf rjmp .-14 ; 0x0 e: f8 cf rjmp .-16 ; 0x0 10: f7 cf rjmp .-18 ; 0x0 12: c7 c1 rjmp .+910 ; 0x3a2, TIMER1 OVF …
有没有办法强制编译器或汇编器只生成 RIP 相关的寻址代码?
我试图找到一种方法来提供从传统编程模型到图灵完备抽象计算模型的映射。
assembly x86-64 machine-language machine-code relative-addressing