我正在阅读John Viega的C和C ++安全编程手册。有一段代码片段,我需要一些帮助才能理解:
asm(".long 0xCEFAEDFE \n"
"crc32_stored: \n"
".long 0xFFFFFFFF \n"
".long 0xCEFAEDFE \n"
);
int main(){
//crc32_stored used here as a variable
}
这些行的确切含义是什么:"crc32_stored:\n"
,".long 0xFFFFFFFF \n"
?这是变量定义和初始化吗?
尝试编译本书中的代码我收到以下错误:
error: ‘crc32_stored’ undeclared (first use in this function)
答案 0 :(得分:3)
crc32_stored:
只是一个标签,汇编程序只是内存地址的别名。由于标签本身不占用目标代码中的任何空间,因此crc32_stored
表示的地址是.long 0xFFFFFFFF
的地址,它汇编为四个FF字节。在目标代码中,标签将显示为符号,这意味着几乎相同的东西(只是地址的别名)。
在C中,变量(在某种程度上)是另一种表达同一事物的方式:一个引用内存中某个地址的名称,但它有其他类型信息,即int
或{{ 1}}。您可以使用long
在C中创建一个变量,其中(减去类型信息)等同于程序集int crc32_stored = 0xFFFFFFFF;
,但这会为另一个地址创建不同的别名。
你可以告诉C编译器不要为名称保留一个新地址" crc32_stored"但是只创建别名部分,然后将其与具有相同名称的符号的地址耦合。这是通过使用" extern"的声明来完成的。存储类说明符,如crc32_stored: .long 0xFFFFFFFF
中所示。通过这个你"承诺"以后链接另一个将具有此符号的目标文件。
显然你必须要注意C类型信息与汇编代码的意图相符(即给定地址有4个字节应该被解释为带符号的32位整数)。
附录: 如果没有额外的声明,则从C代码中看不到符号,因为汇编器部件是单独处理的。由于缺少类型信息,因此无法自动将符号导出为C代码。 (程序集标签甚至不包含有关它是指向数据还是代码的信息。)