Assembly 需要帮助从ADA95程序中解密GNU程序集吗

Assembly 需要帮助从ADA95程序中解密GNU程序集吗,assembly,x86,gnu,ada,Assembly,X86,Gnu,Ada,因此,我得到了一个ADA95程序,以及编译器输出的汇编代码。我很难理解编译器/运行时环境是如何实现非本地访问的。熟悉GNU组装的人能帮我吗?我已经在英特尔汇编和ADA95中编写了很多代码,并且理解GNU汇编的基本语法 以下是Ada计划: PROCEDURE Main_2 IS X : Integer := 1; PROCEDURE Bigsub IS A : Integer := 2; B : Integer := 3;

因此,我得到了一个ADA95程序,以及编译器输出的汇编代码。我很难理解编译器/运行时环境是如何实现非本地访问的。熟悉GNU组装的人能帮我吗?我已经在英特尔汇编和ADA95中编写了很多代码,并且理解GNU汇编的基本语法

以下是Ada计划:

PROCEDURE Main_2 IS
   X : Integer := 1;
   PROCEDURE Bigsub IS
      A : Integer := 2;
            B : Integer := 3; 
            C : Integer := 4;
      PROCEDURE Sub1 IS
         A : Integer := 5; 
                  D : Integer := 6;
      BEGIN -- of Sub1
         A := B + C;  -- point 1
      END; -- of Sub1
      PROCEDURE Sub2 (X : Integer) IS
         B : Integer := 7;
                  E : Integer := 8;
         PROCEDURE Sub3 IS
            C : Integer := 9;
                        E : Integer := 10;
         BEGIN -- of Sub3
            Sub1;
            E := B + A;  -- point 2
         END; -- of Sub3
      BEGIN -- of Sub2
         Sub3;
         A := C + E; -- point 3
      END; -- Sub2
   BEGIN -- of Bigsub
      Sub2(11);
   END; -- of Bigsub
BEGIN -- of Main_2
   Bigsub;
END; -- of Main_2
以下是组装程序:

    .file   "main_2.adb"
    .text
    .align 2
    .def    _main_2__bigsub__sub1.2238; .scl    3;  .type   32; .endef
_main_2__bigsub__sub1.2238:                                 ;;SUB_1 RIGHT HERE
LFB3:
    pushl   %ebp                                            ;;Push current frame pointer onto stack
LCFI0:
    movl    %esp, %ebp                                      ;;assign the current stack point to the current frame pointer
LCFI1:
    subl    $40, %esp                                       ;;Subtract 40 from the stack pointer, making room for 10 longs of data(frame is 10 longs long)
LCFI2:
    movl    %ecx, -28(%ebp)                                 ;;Whatever is in ECX is moved to 28 bytes ahead of the frame pointer
    movl    $5, -12(%ebp)                                   ;;Storing A in Sub1 // A = 5
    movl    $6, -16(%ebp)                                   ;;Storing B in Sub1 // B = 6
    movl    $7, -12(%ebp)                                   ;;Storing A in Sub1 // A = 3 + 4
    leave                                                   ;;Assign the current frame pointer to the current stack pointer. Pop the old frame pointer
LCFI3:
    ret                                                     ;;Returning from SUB_1. Pops the return address off and jumps to it.
LFE3:
    .align 2
    .def    _main_2__bigsub.2231;   .scl    3;  .type   32; .endef
_main_2__bigsub.2231:                                       ;;BIG SUB RIGHT HERE
LFB2:
    pushl   %ebp                                            ;;Push current frame pointer onto stack
LCFI4:
    movl    %esp, %ebp                                      ;;Assign the current stack point to the current frame pointer
LCFI5:
    subl    $56, %esp                                       ;;Subtract 56 from the stack pointer, making room for 14 longs of data(frame is 14 longs long)
LCFI6:
    movl    %ecx, -28(%ebp)                                 ;;Whatever is in the ecx is moved to 28 bytes ahead of the frame pointer
    movl    $2, -20(%ebp)                                   ;;Storing A in BIGSUB // A = 2
    movl    $3, -12(%ebp)                                   ;;Storing B in BIGSUB
    movl    $4, -16(%ebp)                                   ;;Storing C in BIGSUB
    leal    -20(%ebp), %eax                                 ;;Saves the address 20 bytes deep into the frame, and loads it into the EAX
    movl    $11, (%esp)                                     ;;Putting x on top of the stack for sub2
    movl    %eax, %ecx                                      ;;Stores the address 20 bytes deep into the stack frame in the ECX
    call    _main_2__bigsub__sub2.2241                      ;;calling sub2 from bigsub
    leave                                                   ;;Assign the current frame pointer to the current stack pointer. Pop the old frame pointer
LCFI7:
    ret                                                     ;;Returning from BIGSUB. Pops the return address off and jumps to it.
LFE2:
    .align 2
.globl __ada_main_2                                         ;;MAIN_2 RIGHT HERE
    .def    __ada_main_2;   .scl    2;  .type   32; .endef
__ada_main_2:
LFB1:
    pushl   %ebp                                            ;;Push current frame pointer onto the stack
LCFI8:
    movl    %esp, %ebp                                      ;;Assign the current stack pointer to the current frame pointer
LCFI9:
    subl    $24, %esp                                       ;;Subtract 24 from the stack pointer, making room for 6 longs of data(frame is 6 longs long)
LCFI10:
    movl    $1, -12(%ebp)                                   ;;Storing x in Main_2
    leal    -12(%ebp), %eax                                 ;;Saves the address 12 bytes deep into the frame, and loads it into the EAX
    movl    %eax, %ecx                                      ;;Stores the address 12 bytes deep into the stack frame in the ECX
    call    _main_2__bigsub.2231                            ;;calling bigsub from main_2
    leave                                                   ;;Assign the current frame pointer to the current stack pointer. Pop the old frame pointer
LCFI11:
    ret                                                     ;;Returning from MAIN_2. Pops the return address off and jumps to it.
LFE1:
    .align 2
    .def    _main_2__bigsub__sub2__sub3.2250;   .scl    3;  .type   32; .endef
_main_2__bigsub__sub2__sub3.2250:                           ;;SUB_3 RIGHT HERE
LFB5:
    pushl   %ebp                                            ;;Push current frame pointer onto the stack
LCFI12:
    movl    %esp, %ebp                                      ;;Assign the current stack pointer to the current frame pointer
LCFI13:
    pushl   %ebx                                            ;;push whatever is in the EBX onto the stack
LCFI14:
    subl    $36, %esp                                       ;;Subtract 36 from the stack pointer, making room for 9 longs of data(frame is 9 longs long)
LCFI15:
    movl    %ecx, %ebx                                      ;;Whatever is in the ecx is moved to the ebx for storage
    movl    %ecx, -28(%ebp)                                 ;;Whatever is in the ecx is moved to the address 28 deep into the frame
    movl    $9, -12(%ebp)                                   ;;Storing C in Sub3 // C = 9
    movl    $10, -16(%ebp)                                  ;;Storing E in Sub3 // E = 10
    movl    (%ebx), %eax                                    ;;The contents of the address in the EBX is moved to the EAX
    movl    %eax, %ecx                                      ;;The contents of the EAX is moved to the ECX
    call    _main_2__bigsub__sub1.2238                      ;;calling sub1 from sub3
    movl    (%ebx), %eax                                    ;;The contents of the address in the EBX is moved to the EAX
    movl    (%eax), %eax                                    ;;The contents of the address in the EAX is moved to the EAX
    addl    $7, %eax                                        ;;Adding 7 and 2, and storing it in the EAX
    movl    %eax, -16(%ebp)                                 ;;Move the contents of the EAX to the address 16 bytes deep into the current frame
    addl    $36, %esp                                       ;;add 36 back to the stack pointer, erasing what was the current frame
    popl    %ebx                                            ;;Pop whatever used to be in EBX back into EBX
LCFI16:
    popl    %ebp                                            ;;Pop the old frame pointer back into EBP
LCFI17:
    ret                                                     ;;Pop the return address off the stack and jump to it
LFE5:
    .align 2
    .def    _main_2__bigsub__sub2.2241; .scl    3;  .type   32; .endef
_main_2__bigsub__sub2.2241:                                 ;;SUB_2 RIGHT HERE
LFB4:
    pushl   %ebp                                            ;;Push the old frame pointer onto the stack
LCFI18:
    movl    %esp, %ebp                                      ;;Assign the current stack pointer to the current frame pointer
LCFI19:
    pushl   %ebx                                            ;;Push Whatever is in the EBX onto the stack
LCFI20:
    subl    $36, %esp                                       ;;Subtract 36 from the stack pointer, making room for 9 longs of data(frame is 9 longs long)
LCFI21:
    movl    %ecx, %ebx                                      ;;Move whatever is in the ECX to the EBX
    movl    %ecx, -28(%ebp)                                 ;;Whatever is in the ECX is assigned to the address 28 bytes deep into the current frame
    movl    %ebx, -20(%ebp)                                 ;;Assign the contents of EBX to 20 deep into the stack frame
    movl    $7, -12(%ebp)                                   ;;Storing B in Sub2 // B = 7
    movl    $8, -16(%ebp)                                   ;;Storing E in Sub2 // E = 8
    leal    -20(%ebp), %eax                                 ;;Saves the address 20 bytes deep into the frame, and loads it into the EAX
    movl    %eax, %ecx                                      ;;Assign the contents of the EAX to the ECX
    call    _main_2__bigsub__sub2__sub3.2250                ;;calling sub3 from sub2
    movl    $12, (%ebx)                                     ;;Assigning 12 to A in Sub2, A is the address held within the EBX
    addl    $36, %esp                                       ;;Add 36 back into the stack pointer, erasing what was the current frame
    popl    %ebx                                            ;;Pop whatever used to be in the EBX back into the EBX
LCFI22:
    popl    %ebp                                            ;;Pop the old frame pointer back into EBP
LCFI23:
    ret                                                     ;;Pop the return address off the stack and jump to it

如果需要清除任何内容,只需询问:)

看起来外部例程正在将对本地堆栈帧的引用传递给ECX中被调用的例程。但是请给出一个简短的例子,因为这个例子很难理解-在源代码中执行的一些数学运算似乎是由编译器按行展开的。

看起来外部例程正在将对本地堆栈帧的引用传递给ECX中被调用的例程。但是请给出一个简短的例子,因为这个例子很难理解——在源代码中执行的一些数学运算似乎是由编译器按行展开的。

遵循ECX寄存器。若您注意到指令leal,则在每次函数调用之前,都会提取并存储每个作用域的参考帧的地址(用作这些局部变量的偏移量)


这可能足以让Meehan给你评分了

请遵循ECX注册表。若您注意到指令leal,则在每次函数调用之前,都会提取并存储每个作用域的参考帧的地址(用作这些局部变量的偏移量)

这可能足以让Meehan给你评分了

——不是答案--

您可以使用
结束过程\u名称简化注释编码形式

  PROCEDURE Sub1 IS
     A : Integer := 5; 
              D : Integer := 6;
  BEGIN -- of Sub1
     A := B + C;  -- point 1
  END; -- of Sub1
变成:

  PROCEDURE Sub1 IS
     A : Integer := 5; 
              D : Integer := 6;
  BEGIN -- of Sub1
     A := B + C;  -- point 1
  END Sub1;
与“花括号”语言相比,我发现Ada有一点非常好。

--不是答案--

您可以使用
结束过程\u名称简化注释编码形式

  PROCEDURE Sub1 IS
     A : Integer := 5; 
              D : Integer := 6;
  BEGIN -- of Sub1
     A := B + C;  -- point 1
  END; -- of Sub1
变成:

  PROCEDURE Sub1 IS
     A : Integer := 5; 
              D : Integer := 6;
  BEGIN -- of Sub1
     A := B + C;  -- point 1
  END Sub1;

与“大括号”语言相比,我发现Ada有一点非常好。

不知道如何格式化代码,所以我发布了到pastebin的链接,希望这样可以。谢谢,这不太好。你为什么不尝试格式化它呢?在你用来提交问题的页面上有一些说明。我试过了,点击了控制键k,然后粘贴了我的代码。它只包含前几行,然后将所有代码塞进一行。我做错了什么?我还尝试手动将其缩进4和8个空格,但没有效果。若要格式化代码,请将其粘贴到问题中,高亮显示,然后单击
{}
图标。我这样做是为了你的Ada代码;程序集列表更大,但无论如何你也可以考虑这个问题。当你说GNU程序集时,你的意思是“GNU编译器生成的X86程序集”?不知道如何格式化代码,所以我把链接发布到巴斯丁,希望这没问题。谢谢,这不太好。你为什么不尝试格式化它呢?在你用来提交问题的页面上有一些说明。我试过了,点击了控制键k,然后粘贴了我的代码。它只包含前几行,然后将所有代码塞进一行。我做错了什么?我还尝试手动将其缩进4和8个空格,但没有效果。若要格式化代码,请将其粘贴到问题中,高亮显示,然后单击
{}
图标。我这样做是为了你的Ada代码;汇编列表更大,但是无论如何你可以考虑这个问题。当你说GNU程序集时,你的意思是“GNU编译器生成的X86程序集”吗?你建议我张贴什么?我被这件事弄糊涂了。也许你能帮我。我不明白为什么汇编程序中的第一个函数是Sub1,尽管它应该是Main_2。我继续评论我所理解的一切。我很快就会贴出来的。你知道Sub2返回后所有代码的用途吗?它看起来就像是一堆存储的值。有什么我需要担心的吗?非常感谢。sub2之后的代码看起来确实很奇怪。这就像编译器以常量声明或其他形式发出部分代码,但我对AT&T语法不太熟悉。这就是为什么我要你把样本量减少一点。您对此感兴趣的是什么?生成的代码是否没有按预期的方式工作?对。“leal-20(%ebp),%eax”语句或其可读形式:)“lea-eax,ebp-20”将当前堆栈帧的地址加载到eax中,几条指令后将其复制到ecx,然后调用子程序。然后,它使用该指针从调用范围中检索值。是的,编译器在编译时做了一些添加。不是随机的。编译器根据嵌套例程所需的变量计算“显示窗口”的基数。例如,在_main_2__bigsub.2231中,变量A位于ebp-20,其余的在窗口的更高位置。我想我现在已经看完这段代码了,但支持此功能的编译器通常会为此在堆栈上构建一个堆栈帧链接。您建议我发布什么?我被这件事弄糊涂了。也许你能帮我。我不明白为什么汇编程序中的第一个函数是Sub1,尽管它应该是Main_2。我继续评论我所理解的一切。我很快就会贴出来的。你知道Sub2返回后所有代码的用途吗?它看起来就像是一堆存储的值。有什么我需要担心的吗?非常感谢。sub2之后的代码看起来确实很奇怪。这就像编译器以常量声明或其他形式发出部分代码,但我对AT&T语法不太熟悉。这就是为什么我要你把样本量减少一点。您对此感兴趣的是什么?生成的代码是否没有按预期的方式工作?对。“leal-20(%ebp),%eax”语句,或