Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/assembly/5.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
Gcc 二进制和(&;)的操作数无效_Gcc_Assembly_Ld_Gnu Assembler - Fatal编程技术网

Gcc 二进制和(&;)的操作数无效

Gcc 二进制和(&;)的操作数无效,gcc,assembly,ld,gnu-assembler,Gcc,Assembly,Ld,Gnu Assembler,我有这个“程序集”文件(仅包含) 结合此链接器脚本: SECTIONS { "$stack_top" = 0x10000; } 组装产生这个输出 file.s:汇编程序消息: file.s:错误:设置'prot_start'时,`&'的操作数(*UND*和*ABS*部分)无效 file.s:错误:设置'prot_end'时,`&'的操作数(*UND*和*ABS*部分)无效 我怎样才能做到这一点呢?该死的: 中缀运算符有两个参数,一个在两边。运算符具有优先级,但具有相同优先级的操作从

我有这个“程序集”文件(仅包含)

结合此链接器脚本:

SECTIONS {
   "$stack_top"   = 0x10000;
}
组装产生这个输出

file.s:汇编程序消息:
file.s:错误:设置'prot_start'时,`&'的操作数(*UND*和*ABS*部分)无效
file.s:错误:设置'prot_end'时,`&'的操作数(*UND*和*ABS*部分)无效
我怎样才能做到这一点呢?

该死的:

中缀运算符有两个参数,一个在两边。运算符具有优先级,但具有相同优先级的操作从左到右执行除了
+
-
之外,两个参数都必须是绝对的
,并且结果是绝对的


为什么不可能?

您已经链接到了GAS文档,但这种无法使用的理由是什么

答:GAS必须通过ELF对象文件将操作传递给链接器,并且只能像这样传递
+
-
-
只是
+
一个负值)。所以这是ELF格式的一个基本限制,而不仅仅是GAS开发者的懒散

当GAS编译到目标文件时,将执行链接步骤,重新定位将确定符号的最终值

问题:为什么
+
可以被传达,而不是
&

回答:因为
+
是可传递的:
(a+b)+c==a+(b+c)
但是
+
&
不是“一起传递的”:
(a&b)+c!=a和(b+c)

让我们看看
+
是如何通过ELF格式传达的,以说服我们自己
&
是不可能的

如果您不熟悉搬迁,首先了解搬迁是什么:

让我们用另一个会产生相同错误的示例来最小化您的示例:

a: .long s
b: .long s + 0x12345678
/* c: .long s & 1 */
s:
编译和反编译:

as --32 -o main.o main.S
objdump -dzr main.o
输出包括:

00000000 <a>:
   0:   08 00                   or     %al,(%eax)
            0: R_386_32 .text
   2:   00 00                   add    %al,(%eax)

00000004 <b>:
   4:   80 56 34 12             adcb   $0x12,0x34(%esi)
            4: R_386_32 .text
其中:

  • S
    :对象文件中重定位前的值

    重新定位前
    a
    的值==
    08 00 00
    ==
    8
    以小尾端为单位

    重新定位前的
    b
    值==
    80563412
    =
    0x12345680
    ,以小尾端为单位

  • A
    :加数,一个rellocation条目的字段,这里是
    0
    (未显示在
    objdump
    中),所以让我们忘掉它吧

搬迁发生时:

  • a
    将替换为:

    address of text section + 8
    
     address of text section + (0x12345678 + 8)
     ==
     address of text section + 0x12345680
    
    有一个
    +8
    ,因为
    s:
    是文本部分的第8个字节,前面有2个长字符

  • b
    将替换为:

    address of text section + 8
    
     address of text section + (0x12345678 + 8)
     ==
     address of text section + 0x12345680
    
    啊哈,这就是为什么
    0x12345680
    出现在对象文件上的原因

正如我们刚才看到的,只需添加到实际偏移量,就可以在ELF文件上表示
+


但是用这种机制(或者我知道的任何其他机制)无法表达
&
,因为我们不知道文本部分在重新定位后的地址是什么,所以我们不能对其应用
&

可能是另一个
$
或两个?@FrankKotler:我觉得美元没有效果,由于遗留的原因,它们都在我的代码库中。不是吗?我不认为那是真的,但我不确定。我更擅长Nasm语法。@FrankKotler
$
是GAS x86 ELF中的有效符号名字符“在大多数机器上,您也可以在符号名中使用$”,这不应该是问题所在。这是不可能的;-)