我必须在从C调用的汇编代码中初始化CPU寄存器吗?

我必须在从C调用的汇编代码中初始化CPU寄存器吗?,c,assembly,initialization,nasm,cpu-registers,C,Assembly,Initialization,Nasm,Cpu Registers,我在读保罗·卡特的书。它使用NASM,一个调用我的汇编代码的C驱动程序应用程序,以及一个使在汇编中进行基本I/O变得容易的配套库 这就是我将从C调用的函数的样子: segment .text global _asm_main _asm_main: enter 0,0 ; setup routine pusha mov bx, 0034h ; bx = 52 (stored in 16 bits) mov cl, bl

我在读保罗·卡特的书。它使用NASM,一个调用我的汇编代码的C驱动程序应用程序,以及一个使在汇编中进行基本I/O变得容易的配套库

这就是我将从C调用的函数的样子:

segment .text
    global  _asm_main
_asm_main:
    enter   0,0               ; setup routine
    pusha

    mov bx, 0034h   ; bx = 52 (stored in 16 bits)
    mov cl, bl      ; cl = lower 8-bits of bx
    mov eax, ecx
    call print_int

    popa
    mov     eax, 0            ; return back to C
    leave                     
    ret
print_int
函数将存储在
eax
的值打印为整数。但这会将垃圾打印到stdout:

4200244
如果我在使用前使用
mov ecx,0000h
ecx寄存器初始化为0,我将获得预期输出:

52
是否总是需要初始化?如果需要,是否有一种快速方法可以从C或NASM将所有寄存器初始化为0(或用户定义的初始值设定项)

我正在使用XP32、MingW4.4.0和NASM 2.09.04。

是的,这是必需的

在集合中,没有为您做任何事情。

您必须按照您想要的方式初始化每个寄存器

函数
print\u int
打印出
eax
的值。在您的代码中,您仅通过以下分配链分配给
eax
(又称
al
)四个字节中的最低一个:
bl
->
cl
->
al
eax
的其余三个字节未初始化。在例程开始时,代码将继承这三个字节中的所有值。这就是为什么你会收到垃圾

您必须初始化您使用的所有寄存器和内存位置


我的x86汇编有点生疏,但我很确定没有一条指令可以将所有通用寄存器设置为零。如果您愿意,您可能可以编写一个宏来完成这项工作。

我想ASM程序员/编译器只初始化他们将要使用的寄存器。由于我现在对学习ASM非常感兴趣,所以我会一次初始化所有这些错误,并且我希望避免这些错误。我不打算编写大量的ASM代码,但我确实想了解像C这样的语言在较低级别上是如何工作的。谢谢,很公平。由于这只是一个学习练习,一个低技术的方法是在你编写的每个函数的开头复制并粘贴一堆
mov
指令。我今天学到了一些新的东西,我认为对此进行评论可能是相关的。我的代码中的
PUSHA
指令(被NASM替换为
PUSHAD
)将所有寄存器值按一个顺序推送到堆栈中。现在我负责将寄存器初始化为我自己的值。在函数返回之前,我可以调用
POPA
(替换为
POPAD
),它以
PUSHAD
的相反顺序将双字从堆栈弹出到寄存器。所以我不必担心丢失寄存器中以前的数据。@AndrejMitrović:您不需要将所有寄存器归零;如果您想要零扩展移动,只需使用
movzx-eax,cl
。如果需要,只合并到完整寄存器的低位字节,或者有时如果没有任何内容将读取完整寄存器。当然,当调用读取完整EAX的
print\u int
时,情况并非如此。您不需要
输入
pusha
,只需遵循调用约定的规则,就像EBX保留调用一样<但是,code>pusha/
popa
是一种缓慢的方法,可以确保您不会踩到调用方的寄存器。(将问题与不阅读垃圾分开)