【问题标题】:How to write a swap function in assembly?如何在汇编中编写交换函数?
【发布时间】:2015-12-05 04:27:58
【问题描述】:

我一直在试图弄清楚如何为我的程序编写一个 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

【问题讨论】:

  • 在我看来,提供的 2 个参数是指向 32 位整数的指针?如果您没有将指向整数的指针传递给此代码,那么我很可能希望它会出现段错误。也许您只是传递整数值而不是指向整数的指针?
  • 好的,我现在就试试指针。
  • 不,没用。至少,不是指向数组的指针。这是我的 C 代码void program2() { int numA[2] = {5,10}; int *num1 = &amp;numA[0]; int *num2 = &amp;numA[1]; int loop=0; printf("stop3\n"); for(loop=0;loop&lt;=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); }
  • 我得看看整个汇编函数以及它是如何被调用的。

标签: linux assembly x86 segmentation-fault swap


【解决方案1】:

您传递的是值,而不是指针。如果您将原型包含在 C 中,编译器会捕捉到这一点(而不是警告未声明的函数,并假设它采用 int 参数)。

extern int _asSwap(int *a, int *b);

如果您检查了出现段错误的地址,调试器也会发现这一点。

此外,在 C 函数名称前加上 _ 是不正常的。 OS X 在 C 符号名称上添加了 _ 前缀,Linux a.out 也是如此(现在被 ELF 取代)。因此,在某些情况下,您需要在 asm 中使用前导 _,但不要在 C 中使用它。

【讨论】:

  • 是的,你是对的,谢谢。已经有一段时间没有做指针了哈哈。是的,我没有意识到我正在传递取消引用的指针。非常感谢。
  • 有趣的是,指针是我的第一个猜测,而且信息不完整;-)。没有看到他用我要求的代码更新了 cmets 和他的答案。我太慢了。遇到了不同的问题!
猜你喜欢
  • 2016-06-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多