C 程序集,从一个函数到另一个函数的数组填充错误

C 程序集,从一个函数到另一个函数的数组填充错误,c,arrays,assembly,x86,att,C,Arrays,Assembly,X86,Att,具有注释c版本的程序集函数: /* int f (int x) { return x+2; } void map2 (int* um, int * outro, int n) { int i; for (i=0; i<n; i++) *(outro+i) = f(*(um+i)); } */ .text .globl f f: /********************************** prologue ************

具有注释c版本的程序集函数:

/*
int f (int x) 
{ 
    return x+2; 
}

void map2 (int* um, int * outro, int n) 
{
    int i;
    for (i=0; i<n; i++)
      *(outro+i) = f(*(um+i));
}
*/

.text

.globl f
f:
/********************************** prologue *************************************/
    pushl   %ebp        
    movl    %esp, %ebp
    pushl   %ebx        
/********************************************************************************/

    movl    8(%ebp), %eax   /* eax receives x value             */
    addl    $2, %eax         /* return x+2;                      */

/************************************** end *************************************/
    popl    %edi
    popl    %ebx
    movl    %ebp, %esp
    popl    %ebp
    ret
/*********************************************************************************/

.globl map2
map2:
/********************************** prologue *************************************/
    pushl   %ebp        
    movl    %esp, %ebp
    pushl   %ebx
    pushl   %esi
    pushl   %edi            
/********************************************************************************/

    movl    $0, %ebx         /* i = 0; INIT                     */
L1: cmpl    16(%ebp), %ebx  /* if (!(i<n))                     */
    jge     out     

    movl    12(%ebp), %esi  /* esi receives 'outro' (another) address   */
    **movl  %ebx, %ecx      /* moves ebx value for bytes multiplication */
    imul    $4, %ecx         /* 4(int) * i bytes to course          */**
    addl    %ecx, %esi      /* esi points to outro+i                    */

    movl    8(%ebp), %edi   /* edi receives 'um' (one) address          */
    **movl  %ebx, %edx      /* moves ebx value for bytes multiplication */
    imul    $4, %edx         /* 4(int) * i bytes to course          */**
    addl    %edx, %edi      /* edi points to um+i                       */ 

/************************ calls f and return it's value *************************/
    pushl   %ecx
    pushl   %edx
    pushl   %eax

    pushl   (%edi)          /* push *(um+i) for 'f' usage           */
    call    f
    movl    %eax, (%esi)    /* *(outro+i) = f(*(um+i));             */
    addl    $4, %esp         /* clears *(um+i) from stack            */

    popl    %eax
    popl    %edx
    popl    %ecx
/********************************************************************************/

    incl    %ebx            /* i++;                     */
    jmp     L1              /* end loop                 */

out:
/************************************** end *************************************/
    popl    %edi
    popl    %esi
    popl    %ebx
    movl    %ebp, %esp
    popl    %ebp
    ret
/********************************************************************************/


很明显,“f”函数是可以的,但是“map2”有一些问题。从b[4]到b[7]获取内存垃圾。这里怎么了?
我的猜测是关于代码末尾的
popl%edi
popl%esi
,因为它们包含两个数组地址。即使如此,那里的更改并没有解决问题。

我无法在这里重现您的问题:/你是什么意思?你的机器运转得很好。对我得到了两次运行的相同输出。i、 e
map2
工作正常。然后它比我想象的还要奇怪o_oNo,你的
f
不正常。它有一个
pop%edi
,但从未推送
%edi
mov%ebp,%esp
将修复它引起的堆栈不平衡,但它仍将破坏调用方所依赖的
edi
#include <stdio.h>
#define N 10

int f (int x);
void map2 (int* um, int * outro, int n);

int main (void) {
    int i;
    int a[N], b[N];

    for (i=0;i<N;i++)
    {
        a[i] = i;
        printf("b[%d] = %d\n", i, f(i));    // added for debug purposes
    }

    map2(a,b,N);
    printf("\n");                           // added for clear sight

    for (i=0;i<N;i++)
        printf("b[%d] = %d\n", i, b[i]);

    return 1;
}
b[0] = 2
b[1] = 3
b[2] = 4
b[3] = 5
b[4] = 6
b[5] = 7
b[6] = 8
b[7] = 9
b[8] = 10
b[9] = 11
b[0] = 33686018 
b[1] = 33686019 
b[2] = 516 
b[3] = -253 
b[4] = -145333866 
b[5] = -143814668 
b[6] = -145333723 
b[7] = -143596928  
b[8] = 0 
b[9] = 134513961
<seg fault>