【问题标题】:Stack in NASM assemblyNASM 组件中的堆栈
【发布时间】:2017-02-13 04:40:37
【问题描述】:

我正在尝试将这段 c 代码转换为 64 位 nasm

int gcd ( int a, int b )
{
  int c;
  while ( a != 0 ) {
     c = a; 
     a = b%a;  
     b = c;
  }
  return b;
}

但我不确定我的错误在哪里,我想也许汇编中的堆栈有一些我不知道的东西 这就是我所做的

打电话

push word[max]
push word[min]
call gcf
pop word[num1_ones]

堆栈函数

gcf:
    mov ebp, esp
while:
    cmp word[ebp+4], 0
    je return

    mov dx, 0
    mov ax, word[ebp+6]
    mov bx, word[ebp+4]
    div bx                                  

    mov word[ebp+4], dx         
    mov word[ebp+6], bx         

    jmp while

return:
    ret 2

当我运行它时,我得到了这个:

【问题讨论】:

  • 那么当你运行它时会发生什么?看起来它应该组装起来。但是你没有描述问题是什么,所以这不是minimal reproducible example

标签: assembly x86 stack nasm


【解决方案1】:

明显缺少的是 EBP 的推送/弹出。

另外,您是在 16 位还是 32 位模式下运行它?这会影响 CALL 推送的返回地址的大小,这会影响您的偏移量......在您阐明如何构建/运行它之前,我不能说更具体的内容。

我建议使用调试器来查看寄存器/内存。

【讨论】:

  • 抱歉,我编辑了我的问题,希望现在更清楚一点。我使用的是 64 位 nasm,我的代码中没有任何错误或分段错误,但我得到的输出不正确。
  • @Samantha:文字图片比实际文字差很多;您应该从终端复制/粘贴到代码块中以说明输出。
  • @Samantha:我很惊讶mov ebp, esp 在 64 位模式下不会导致段错误,因为您将 RSP 截断为 32 位。通常堆栈不在低 4GB 的虚拟内存中。因此,您实际上可能正在构建 32 位代码,但您可以包含用于确认这一点的命令。同样令人惊讶的是,您的程序在函数返回后没有崩溃,因为您没有保留调用者的 RBP
  • @Samantha:无论哪种方式,您绝对应该使用调试器并单步执行您的函数,同时观察寄存器值的变化。您可能还对code-golf x86 gcd function 感兴趣,它针对机器代码大小(8 字节)进行了优化,而不是为了可读性,但它与您使用的算法完全相同。它将值保存在寄存器中,而不是存储/重新加载到内存中。关于同一个代码高尔夫问题的另一个 x86 asm 答案没有我的优化,但更具可读性。
猜你喜欢
  • 1970-01-01
  • 2013-10-12
  • 1970-01-01
  • 2013-08-13
  • 1970-01-01
  • 1970-01-01
  • 2020-05-18
  • 2015-04-26
  • 2013-03-05
相关资源
最近更新 更多