Assembly 需要帮助从ADA95程序中解密GNU程序集吗
因此,我得到了一个ADA95程序,以及编译器输出的汇编代码。我很难理解编译器/运行时环境是如何实现非本地访问的。熟悉GNU组装的人能帮我吗?我已经在英特尔汇编和ADA95中编写了很多代码,并且理解GNU汇编的基本语法 以下是Ada计划: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;
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”语句,或