IA32汇编语言堆栈跟踪

时间:2014-11-19 22:33:16

标签: c x86 stack trace ia-32

我一直在努力解决我在大学实验室收到的IA32汇编语言问题。我不能完全理解如何去做,并想知道这里是否有人可以帮助我。

问题是:在执行期间从以下几点绘制运行时堆栈,从传递给fact_do的参数开始,到堆栈顶部结束。在每种情况下标记每个4字节的存储位置并在已知时指示内容。显示%ebp和%esp指向的位置。

我无法完全绘制堆栈跟踪的观点是:“就在事实中的离开指令之前(离开相当于movl%ebp,%esp后跟popl%ebp)。”

我认为所期望的是:

 _____________
|             |  <- %ebp
| .           |
| .           |
| .           |
|_____________|
|_5___________|
|_Rtn_Address_|  <- %esp

以下是要跟踪的代码:

    .file    "fact.c"
    .section    .rodata
.LC0:
    .string    "%d! = %d\n"        #string is initialized
    .text
.globl main
    .type    main, @function
main:
    pushl    %ebp
    movl    %esp, %ebp
    andl    $-16, %esp
    subl    $16, %esp
    movl    $5, (%esp)        #(%esp) <- 5         [(%esp) = n]
    call    fact_do
    movl    $.LC0, %edx    #set up print statement
    movl    %eax, 8(%esp)        #8(%esp) <- %eax     [%eax = 120, return value of fact_do]
    movl    $5, 4(%esp)        #4(%esp) <- 5
    movl    %edx, (%esp)        #print statement location
    call    printf            #print output
    movl    $0, %eax        #%eax <- 0
    leave
    ret
    .size    main, .-main
.globl fact_do
    .type    fact_do, @function
fact_do:
    pushl    %ebp            #push %ebp onto stack
    movl    %esp, %ebp        #%ebp <- %esp
    subl    $16, %esp        #%esp <- %esp - 16
    movl    $1, -4(%ebp)        #-4(%ebp) <- 1        [-4(%ebp) = result]
.L4:
    movl    -4(%ebp), %eax        #%eax <- -4(%ebp)
    imull    8(%ebp), %eax        #%eax <- %eax * 8(%ebp) [8(%ebp) = n]
    movl    %eax, -4(%ebp)        #-4(%ebp) <- %eax     [result <- result*n]
    subl    $1, 8(%ebp)        #8(%ebp)--           [n--]
    cmpl    $1, 8(%ebp)        #8(%ebp) > 1 ?         [n > 1]
    jg    .L4                 #Repeat loop if 8(%ebp) > 1
    movl    -4(%ebp), %eax        #%eax <- -4(%ebp)     [%eax <- 120, result]
    leave
    ret
    .size    fact_do, .-fact_do
    .ident    "GCC: (GNU) 4.4.7 20120313 (Red Hat 4.4.7-4)"
    .section    .note.GNU-stack,"",@progbits
Optimized:
    .file    "fact.c"
    .text
.globl fact_do
    .type    fact_do, @function
fact_do:
    pushl    %ebp            #push %ebp (for return)
    movl    %esp, %ebp           #%ebp <- %esp
    movl    8(%ebp), %edx            #%edx <- 8(%ebp) [%edx = n]
    movl    $1, %eax                #%eax <- 1 [%eax = result]
.L2:
    imull    %edx, %eax           #%eax <- %edx * %eax [result <- n * result]
    subl    $1, %edx                #%edx-- [n--]
    cmpl    $1, %edx                #%edx > 1 ? [n > 1]
    jg    .L2                    #repeat if %edx > 1 [if n > 1]
    popl    %ebp                #%ebp <- top value on stack (for return)
    ret
    .size    fact_do, .-fact_do
    .section    .rodata.str1.1,"aMS",@progbits,1
.LC0:
    .string    "%d! = %d\n"        #prepare string
    .text
.globl main
    .type    main, @function
main:
    pushl    %ebp
    movl    %esp, %ebp
    andl    $-16, %esp
    subl    $16, %esp
    movl    $5, (%esp)            #%esp <- 5
    call    fact_do
    movl    %eax, 8(%esp)            #8(%esp) <- %eax [%eax = result]
    movl    $5, 4(%esp)            #4(%esp) <- 5
    movl    $.LC0, (%esp)            #set up print statement
    call    printf               #print
    movl    $0, %eax                #%eax <- 0
    leave
    ret
    .size    main, .-main
    .ident    "GCC: (GNU) 4.4.7 20120313 (Red Hat 4.4.7-4)"
    .section    .note.GNU-stack,"",@progbits

在C中转换为以下内容:

#include <stdio.h>
int fact_do(int n);
int main(){
    printf("%d! = %d\n", 5, fact_do(5));
    return 0;
}

int fact_do(int n){
   int result = 1;
   do {
       result *= n;
       n = n-1;
   } while (n > 1);
   return result;
}

0 个答案:

没有答案