您非常具体的问题的非常具体的答案是因为 long 没有固定的大小定义。当第一个 32 位 x86 处理器问世并开始 16 位到 32 位的转换时,许多编译器的 int 从 16 位更改为 32 位。但是 long int 保持在 32 位。这种情况一直持续到 64 位 x86 处理器问世并且 / 一些流行的编译器将 long 更改为 64 位而 int 保持 32 位。
但是 int 或 long 位的定义是编译器作者的选择,语言规范中使用术语“实现定义”来涵盖这一点。因此,同一编译器的一个编译器或编译器版本很可能解释为 32 位长,而另一个编译器或相同编译器的版本对于同一目标解释为 64 位。这就是 stdint.h 的来源,它有点像 hack,但基于 C 语言的时代和历史以及许多编译器,他们没有太多选择。
现在,如果您进一步举例编译器输出,您可能/将会发现一些编译器使用较大的寄存器 eax/rax 并避免 al/bl ah/bl 操作,这部分与微编码和性能有关。所以 cmpl 和 eax/edx 告诉你故事的开始,直接阅读你的汇编器文档以了解它的汇编语言(汇编语言是由汇编器定义的,工具,而不是芯片/逻辑设计器,尽管它们通常很相似芯片/IP 供应商文档)。然后考虑到一些编译器可以对较小的变量使用相同的特定指令(但当然不是更大)的可能性。
但是这个程序集与提供的 C 代码不匹配,除非 int 的定义是 8 位。教科书暗示int的定义是32位。所以这是一个可怕且非常糟糕的例子。如果教科书的其余部分是这样的,我祝你好运。无论如何,x86 是错误的第一个学习指令集,永远不应该用于教授此类主题。许多/大多数其他人会更好地为您服务。我相信你可能别无选择,所以你的任务要困难得多。
您可以/应该做的是获取该代码,获取您拥有的一个或多个编译器并为 data_t 和 COMP 提供定义,然后看看您得到了什么。C 代码中的 _t 意味着 stdint.h 的知识,因此将这些定义用于您的测试代码和您对该作业的答案。