Sign Up

Sign Up to our social questions and Answers Engine to ask questions, answer people’s questions, and connect with other people.

Have an account? Sign In

Have an account? Sign In Now

Sign In

Login to our social questions & Answers Engine to ask questions answer people’s questions & connect with other people.

Sign Up Here

Forgot Password?

Don't have account, Sign Up Here

Forgot Password

Lost your password? Please enter your email address. You will receive a link and will create a new password via email.

Have an account? Sign In Now

You must login to ask a question.

Forgot Password?

Need An Account, Sign Up Here

Please briefly explain why you feel this question should be reported.

Please briefly explain why you feel this answer should be reported.

Please briefly explain why you feel this user should be reported.

Sign InSign Up

The Archive Base

The Archive Base Logo The Archive Base Logo

The Archive Base Navigation

  • SEARCH
  • Home
  • About Us
  • Blog
  • Contact Us
Search
Ask A Question

Mobile menu

Close
Ask a Question
  • Home
  • Add group
  • Groups page
  • Feed
  • User Profile
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Buy Points
  • Users
  • Help
  • Buy Theme
  • SEARCH
Home/ Questions/Q 7278763
In Process

The Archive Base Latest Questions

Editorial Team
  • 0
Editorial Team
Asked: May 28, 20262026-05-28T22:55:08+00:00 2026-05-28T22:55:08+00:00

So, I was given an Ada 95 program, and the assembly code that the

  • 0

So, I was given an Ada 95 program, and the assembly code that the compiler spits out. I’m having trouble understanding how the compiler/run-time environment are implementing non-local accesses. Could anybody familiar with GNU assembly help me? I have coded lots in Intel assembly and Ada 95, and understand the basic syntax of GNU assembly.

Here’s the Ada program:

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

Here’s the assembly program:

    .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

If I need to clear anything up just ask 🙂

  • 1 1 Answer
  • 0 Views
  • 0 Followers
  • 0
Share
  • Facebook
  • Report

Leave an answer
Cancel reply

You must login to add an answer.

Forgot Password?

Need An Account, Sign Up Here

1 Answer

  • Voted
  • Oldest
  • Recent
  • Random
  1. Editorial Team
    Editorial Team
    2026-05-28T22:55:09+00:00Added an answer on May 28, 2026 at 10:55 pm

    Looks like the outer routine is passing a reference to the local stack frame to the called routine in ECX. But please post a shorter example since this one is hard to follow – some of the math performed in the source appears to be expanded in line by the compiler.

    • 0
    • Reply
    • Share
      Share
      • Share on Facebook
      • Share on Twitter
      • Share on LinkedIn
      • Share on WhatsApp
      • Report

Sidebar

Related Questions

Given below is some code in ada with TYPE_VECT_B; use TYPE_VECT_B; Package TEST01 is
in the quest to make an Ada code run faster, I'm including the pragma
Given a specific DateTime value, how do I display relative time, like: 2 hours
Given the following code from a Microsoft example: public class EngineMeasurementCollection : Collection<EngineMeasurement> {
Given an Ada protected type: protected type A is procedure Foo; ... private M
Given the following hash: {7=>Ada (gnat-4.3.2), 13=>Assembler (nasm-2.07), 45=>Assembler (gcc-4.3.4), 104=>AWK (gawk) (gawk-3.1.6), 105=>AWK
Given a tree, how to find the centre node in the tree so that
Given that I have the array Let Sum be 16 dintptr = { 0
Given this Python program: num = input(Enter a number: ) result = 1024 for
Given long long int x, y; , I want a function that can compare

Explore

  • Home
  • Add group
  • Groups page
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Users
  • Help
  • SEARCH

Footer

© 2021 The Archive Base. All Rights Reserved
With Love by The Archive Base

Insert/edit link

Enter the destination URL

Or link to existing content

    No search term specified. Showing recent items. Search or use up and down arrow keys to select an item.