使用包含指令填充数组

问题描述 投票:0回答:2

[今天早上,我了解到著名的视频游戏《超级马里奥64》已经完全反编译为C源代码。出于好奇,我决定仔细检查一下,然后发现一些我从未见过的东西。

// 0x09000000
ALIGNED8 const u8 machine_09000000[] = {
#include "textures/machine/ttc_textures.00000.rgba16.inc.c"
};

似乎他们将include指令放置在数组中。在整个程序中重复进行此操作。我学习C已有一段时间了,我认为自己能熟练使用这种语言,但这对我来说是非常新颖的东西,对此我有很多疑问。

1)做这样的事情实际上合法还是什至建议这样做?2)为什么要这样做?3)为什么include引用* .c文件?4)为什么将类型设置为u8(如果我直接知道的话,它应该是unsigned char的标准别名)?5)ALIGNED8宏是什么?这是标准吗?

我试图独自收集信息,但是在这个主题上找不到很多。如果您想亲自查看源代码,请点击以下链接:https://github.com/n64decomp/sm64

arrays include static-linking precompile
2个回答
0
投票

[在开始任何事情之前,我首先建议使用附加到该存储库的Discord链接discord.gg/27JtCWs。我将尽力回答这个问题,但是绝对不是最一般的编码标准和典型行为的知识。我的经验仅与我有关,因为我与参与反编译的一些人紧密合作。

1&2。我不认为这通常是一件理智的事情,但是重要的是要记住回购的要点-轻松修改代码库,同时保留编译1:1 ROM的能力的SM64。对文件进行拆分使查找事物的相关位置更加容易,尽管该特定文件尚未很好地命名。

  1. 因此inc.c文件是精美的头文件,只需将其代码插入该位置。之所以命名为.c文件,是因为它是C语言,而不是合法的C文件本身。这就是为什么它是.inc.c的原因,因为它包含在内>

  2. 这是一个标准的无符号字符,正确。可以在types.h中找到。这样做是因为实际上它只是导入了一堆可以单独读取的数据。该特定文件不在存储库中,但是如果您提取资产,则可以看到是在其中插入了图像。图像的数据仅被拆分为u8并放在其中,从而可以将其提取/插入并更容易地进行编辑。

  3. ALIGNED8用于编译器。存储库使用的IDO 5.7编译器通常将ROM输出中的内容对齐,并且ALIGN8指令告诉它填充8个字节。如果ALIGNED8不存在,则可能会过早插入该数据,从而移动ROM。

希望我没有犯任何错误,这会有所帮助。重要的是要记住,整个GitHub并不是真正的一个,因为它不再担心内部一致性,而更担心外部(ROM)一致性,这通常意味着有时必须对解决方案进行分类以允许功能。如果您还有其他问题,我将再次建议您在Discord中进行询问,因为这些人比我了解得多。


0
投票

来自一个比我聪明的家伙-

1&2:我们包括一张转换为C的图像。除了.c代码中的数组以外,还有其他技术,但这是sm64开发人员使用的技术,因此我们将其模拟。而不是复制粘贴C数组,我们让构建系统自动从图像生成C(部分),然后将其包含#include。它工作得很好,在这种情况下我们会尽力而为。 (假设我们希望将所有内容都保留在C中而不是汇编中-在汇编中,我们希望.incbin会更干净,但它的可移植性会降低。)

3:.h是错误的,因为它不是声明函数,类型等的头文件,而是声明数据(部分C文件)

  1. 这是u8,因为我们包含的文件只是数据的二进制blob,我们不想做字节序假设

  2. ALIGNED8实际上在IDO上被忽略。它的作用是在GCC上将阵列8字节对齐。原因是发送到RSP的地址必须是8字节对齐的,如果没有这样的指令就无法保证。特别是,GCC很高兴以使变量不与8字节对齐的方式对变量进行重新排序。 IDO不会进行这种重新排序(它只是按源顺序发出数组),但是无论如何,这些变量恰好以8字节对齐的方式结束。有助于了解#include的作用,即只是包含另一个文件的文本根据该定义,可以肯定的是,在这种情况下使用它绝对合法;是否明智是另一个问题。

© www.soinside.com 2019 - 2024. All rights reserved.