Assembly 寄存器是否有默认值?

Assembly 寄存器是否有默认值?,assembly,Assembly,我试图理解一点代码: jg 0x00000047 dec esp inc esi add [ecx],eax eax的价值是多少?这是程序的前四个句子,我不知道是否有默认值,或者前面的句子是否为eax添加了一些内容 我的操作系统是Linux,可执行文件由gcc4.3从C源代码(gcc file.C exec)编译而成。取决于平台、语言和/或调用约定。但是,是的,在此之前的代码通常应该将EAX设置为某个值。EAX是那些经常被修改的寄存器之一,它通常不用于在内存中保存内容 说明看起来有点随意。特别

我试图理解一点代码:

jg 0x00000047
dec esp
inc esi
add [ecx],eax
eax的价值是多少?这是程序的前四个句子,我不知道是否有默认值,或者前面的句子是否为eax添加了一些内容


我的操作系统是Linux,可执行文件由gcc4.3从C源代码(gcc file.C exec)编译而成。

取决于平台、语言和/或调用约定。但是,是的,在此之前的代码通常应该将EAX设置为某个值。EAX是那些经常被修改的寄存器之一,它通常不用于在内存中保存内容


说明看起来有点随意。特别是,“dec-esp”通常是一个巨大的no-no,因为堆栈应该始终是双字对齐的。你确定这是实际代码吗?如果我翻译正确,指令字节将转换为“\x7fELF”,这向我表明这只是Linux程序的头字节,而不是实际的代码字节。

有些指令会隐式更新寄存器,即使代码中没有明确列出目标。一些例子:

  • cpuid
    返回eax、ebx、ecx和edx中的值
  • 循环
    减少ecx
  • rep
    字符串指令更改ecx、edi和esi
  • rdmsr
    更改eax和edx
  • mul
    div
    更改eax和edx
还有很多其他的例子

您不能仅仅通过看到代码中没有列出eax就认为它没有更改

即使您知道哪些寄存器受哪些指令的影响,您对某个值有任何保证的唯一时间是:

  • 在您知道的指令更新之后
  • 硬件复位后立即

在其他任何时候,您都不能对这些值进行假设。

这似乎不是有效的代码。你确定不是短信吗

将其解码为32位x86将产生字符串
ELF

00: 7F 45  // 0x7F E
02: 4C     // L
03: 46     // F
04: 01 01  // ?? ??

尝试将文件作为ELF文件打开,而不仅仅是二进制文件。

我认为您真正想问的是,它描述了程序中的子程序如何相互传递信息,操作系统如何将信息传递给程序,以及不同寄存器的一般含义

例如,大多数C编译器使用的表示,当函数返回时,返回值将进入eax寄存器。因此,如果您有一个函数
intfoo()
,您就知道
foo
执行其操作码后,eax将包含
foo
返回的int

相比之下,PowerPC处理器(通常)至少有32个寄存器,简称为r0、r1、。。。r31。对于这个芯片,堆栈指针指向r1,函数参数通过r3传递到r11,返回值返回到r3,等等

重要的是要记住,调用约定有点像程序中的函数之间或库之间的协议。它不是硬件的一部分,也不是法律,通常在一个平台上可以使用许多不同的调用约定。这就是为什么有时您会看到这样的代码

struct CFoo {  void __stdcall method(); };
这是对MSVC的一条指令,MSVC通常喜欢使用约定,告诉它对该函数使用不同的约定。如果函数是在由其他编译器构建的库中定义的,那么这一点很重要


当我们谈论操作系统如何将信息传递给程序(或硬件传递给操作系统)时,我们通常称之为调用约定,而不是调用约定,但这是相同的想法。因此,在您的程序中,它的编写假设操作系统将在eax上向它传递一些特定的信息。这一假设对于操作系统、编译器,甚至可能是单个程序都是特定的。

因此我们可以说eax有一个随机(至少对我来说是随机)值?如果您提供一些关于您的平台(操作系统,可执行格式)的信息,我相信有人可以告诉您在程序入口点设置了什么。eax,谢谢你的建议。为了理解asm代码,我反汇编了我用C写的一些程序代码,我想它们不是随机指令。正如我所说,没有前面的句子,所以eax可能有一个随机值。谢谢。你是如何反汇编代码的?请记住,可执行文件很少只是原始代码。(我所知道的唯一格式是.com文件,这些文件已经过时10多年了。)在大多数32位操作系统中,可执行文件的格式非常复杂。如果x86dis知道如何反汇编ELF程序,也许。但它看起来有点不那么聪明。所以这就是我现在的问题,谢谢。我会尽量把它拆开。非常感谢,这让我很好地理解了ASM。