Нужна помощь в расшифровке сборки GNU из программы Ada 95

Итак, мне дали программу на языке Ada 95 и ассемблерный код, который выдает компилятор. У меня проблемы с пониманием того, как среда компилятора / времени выполнения реализует нелокальный доступ. Может ли мне помочь кто-нибудь, знакомый с сборкой GNU? Я написал много кода на сборке Intel и Ada 95 и понимаю базовый синтаксис сборки GNU.

Вот программа на Аде:

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

Если мне нужно что-то прояснить, просто спросите :)

0
задан Jens Björnhager 18 December 2012 в 23:31
поделиться