Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/67.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/assembly/6.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C 如何在动态链接库中引用全局变量?_C_Assembly_Solaris_Dynamic Linking_Sparc - Fatal编程技术网

C 如何在动态链接库中引用全局变量?

C 如何在动态链接库中引用全局变量?,c,assembly,solaris,dynamic-linking,sparc,C,Assembly,Solaris,Dynamic Linking,Sparc,环境是32位SPARC上的Solaris,但我认为这是动态链接和/或位置独立代码的一个更普遍的问题 我有一个汇编程序,我编译为独立于位置的代码,并从C程序动态链接到它。它工作正常,只是我不能从汇编程序中引用汇编程序保留的任何内存。在汇编程序中跳转工作正常 我只想在汇编程序中读写内存,但每次尝试都会出现分段错误 我编写这个测试程序是为了调试这个问题 .section ".data" .global foo foo: .word 1 .section ".text" .global

环境是32位SPARC上的Solaris,但我认为这是动态链接和/或位置独立代码的一个更普遍的问题

我有一个汇编程序,我编译为独立于位置的代码,并从C程序动态链接到它。它工作正常,只是我不能从汇编程序中引用汇编程序保留的任何内存。在汇编程序中跳转工作正常

我只想在汇编程序中读写内存,但每次尝试都会出现分段错误

我编写这个测试程序是为了调试这个问题

  .section ".data"
  .global foo
foo: .word 1
  .section ".text"
  .global testprog
testprog:
  save %sp, -(92+4), %sp
  sethi %hi(foo), %o0 ! set foo, %o0
  or %o0, %lo(foo), %o0 
  call print_int
  nop
  ret
  restore
我把它编译成

as-K PIC-b

然后打开结果。在C中也是如此

dlhandle = dlopen(obj_file, RTLD_NOW)
dl_testprog = dlsym(dlhandle, "testprog")
当我调用
dl_testprog()
时,它会打印“4”。如果我试图打印testprog或print_int的地址,它也会打印“4”。跳转到标签,其他一切都可以正常工作。在反汇编中,foo被0x0替换,这是应该的


我是否必须通过
\u GLOBAL\u OFFSET\u TABLE\u
或其他程序,才能在汇编程序中写入自己的内存?如果是,我该怎么做?我尝试的每件事都导致了一个SEGFULT,我还没有找到一个很好的指南如何做到这一点(这让我相信你不应该这么做。这不是链接器的问题吗?)。

是的,我相信你必须通过访问才能处理私人数据。见第9.2节。尽管NASM是x86汇编程序,但在SPARC/Solaris上的一般原则也应该相同


此外,AT&T汇编程序通常使用“@got”语法来指定重新定位wrt。得到了。确切的细节将在您的汇编程序手册中描述,即NASM的语法细节将不适用于Solaris的汇编程序。

通过查看C编译器为PIC输出的代码解决了这个问题,这是我从一开始就应该做的,而不是阅读手册和随机网页

也许这是显而易见的,但实际上PIC中一个对象的真实地址(至少在32b SPARC上)是(
\u GLOBAL\u OFFSET\u TABLE\u+PC+object
)。约定是在函数开头计算到%l7的GET地址。除了如何实际计算%l7之外,详细信息如下所示

addpc:
  add %o7, %l7, %l7 ! %o7 == addr of call == PC
  retl
   nop
testprog:
  sethi %hi(_GLOBAL_OFFSET_TABLE_-8), %l7 ! -8 = distance from call addpc
  add %l7, %lo(_GLOBAL_OFFSET_TABLE_-4), %l7 
  call addpc ! add PC to %l7
   nop

+1查看C汇编输出:-)(几年前帮助我在m68k上编写了一个非常快速和优化的中断处理程序。我只是在C中启动它,获取ASM输出并对其进行优化…在该项目之前没有为m68k编写汇编程序)。