如何在汇编中编写交换函数?
How to write a swap function in assembly?
我一直在想办法为我的程序编写一个 x86 GAS 交换函数。我知道做 xchg 或直接写 C 更容易,但我还是希望能够把它写出来。
在我的第一次期中考试中,我们得到了这个作为交换函数:
movl 8(%ebp), %edx
movl 12(%ebp), %ecx
movl (%edx), %ebx
movl (%ecx), %eax
movl %eax, (%edx)
movl %ebx, (%ecx)
但是当 运行 这个时候我收到了一个分段错误。无法在网络上的其他任何地方成功找到我的答案,将不胜感激。
编辑:
C 代码:
void program2()
{
int numA[2] = {5,10};
int *num1 = &numA[0];
int *num2 = &numA[1];
int loop=0;
printf("stop3\n");
for(loop=0;loop<=10;loop++)
{
*num1 *=2;
*num2 *=3;
printf("%d\n%d\n",*num1,*num2);
_asSwap(*num1,*num2);
printf("stop5\n");
printf("P2num1= %d\n P2num2= %d\n",*num1,*num2);
}
程序集:
_asSwap:
push %ebp
movl %esp, %ebp
movl 8(%ebp), %edx
movl 12(%ebp), %ecx
movl (%edx), %ebx
movl (%ecx), %eax
movl %eax, (%edx)
movl %ebx, (%ecx)
pop %ebp
ret
您传递的是值,而不是指针。如果您将原型包含在您的 C 中,编译器会捕捉到它(而不是警告未声明的函数,并假设它采用 int 参数)。
extern int _asSwap(int *a, int *b);
如果您检查发生段错误的地址,调试器也会发现这一点。
此外,在 C 函数名称前加上 _
是不正常的。 OS X 在 C 符号名称上加上前缀 _
,Linux a.out 也是如此(现在被 ELF 取代)。所以在某些情况下,您需要在 asm 中使用前导 _
,但不要在 C 中使用它。
我一直在想办法为我的程序编写一个 x86 GAS 交换函数。我知道做 xchg 或直接写 C 更容易,但我还是希望能够把它写出来。
在我的第一次期中考试中,我们得到了这个作为交换函数:
movl 8(%ebp), %edx
movl 12(%ebp), %ecx
movl (%edx), %ebx
movl (%ecx), %eax
movl %eax, (%edx)
movl %ebx, (%ecx)
但是当 运行 这个时候我收到了一个分段错误。无法在网络上的其他任何地方成功找到我的答案,将不胜感激。
编辑:
C 代码:
void program2()
{
int numA[2] = {5,10};
int *num1 = &numA[0];
int *num2 = &numA[1];
int loop=0;
printf("stop3\n");
for(loop=0;loop<=10;loop++)
{
*num1 *=2;
*num2 *=3;
printf("%d\n%d\n",*num1,*num2);
_asSwap(*num1,*num2);
printf("stop5\n");
printf("P2num1= %d\n P2num2= %d\n",*num1,*num2);
}
程序集:
_asSwap:
push %ebp
movl %esp, %ebp
movl 8(%ebp), %edx
movl 12(%ebp), %ecx
movl (%edx), %ebx
movl (%ecx), %eax
movl %eax, (%edx)
movl %ebx, (%ecx)
pop %ebp
ret
您传递的是值,而不是指针。如果您将原型包含在您的 C 中,编译器会捕捉到它(而不是警告未声明的函数,并假设它采用 int 参数)。
extern int _asSwap(int *a, int *b);
如果您检查发生段错误的地址,调试器也会发现这一点。
此外,在 C 函数名称前加上 _
是不正常的。 OS X 在 C 符号名称上加上前缀 _
,Linux a.out 也是如此(现在被 ELF 取代)。所以在某些情况下,您需要在 asm 中使用前导 _
,但不要在 C 中使用它。