C 程序集,从一个函数到另一个函数的数组填充错误
具有注释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 ************
/*
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、 emap2
工作正常。然后它比我想象的还要奇怪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>