【问题标题】:x86 Assembly program does not terminatex86 汇编程序不终止
【发布时间】:2014-09-30 02:29:59
【问题描述】:

我正在学习汇编,我的任务是将一个简单的程序从 32 位转换为 64 位。程序计算 2^3 + 5^2。我的程序编译得很好,但是,当我运行它时,程序并没有终止。因此,我必须在命令行中按 Ctrl + C 才能真正停止程序。我认为问题最初是因为我使用int 0x80 终止,但在我切换到syscall 后问题仍然存在。

代码:

  1 .section .data
  2 .section .text
  3 .globl _start
  4 _start:
  5         push $3
  6         push $2
  7 
  8         call power
  9         addq $8, %rsp
 10 
 11         push %rax
 12 
 13         push $2
 14         push $5
 15 
 16         call power
 17         addq $8, %rsp
 18         pop %rbx
 19 
 20         addq %rax, %rbx
 21 
 22         movq $1, %rax
 23         syscall
 24 
 25 .type power, @function
 26 power:
 27         push %rbp
 28         movq %rsp, %rbp
 29         subq $4, %rsp
 30 
 31         movq 8(%rbp), %rbx
 32         movq 12(%rbp), %rcx
 33 
 34         movq %rbx, -4(%rbp)
 35 
 36 power_loop_start:
 37         cmpq $1, %rcx
 38         je end_power
 39 
 40         movq -4(%rbp), %rax
 41         imulq %rbx, %rax
 42         movq %rax, -3(%rbp)
 43         decq %rcx
 44         jmp power_loop_start
 45 
 46 end_power:
 47         movq -4(%rbp), %rax
 48         movq %rbp, %rsp
 49         pop %rbp
 50         ret

很抱歉发布这么多代码,但我需要指导,因为我完全一无所知。我已经搜索了很长时间,但无济于事。提前致谢。顺便说一句,该程序在将其转换为 64 位之前工作。我只是将所有 movl 等更改为 movq 并使用 64 位寄存器。

【问题讨论】:

  • 了解如何使用调试器。做一些调试。然后问。
  • 明白。我建议您在 gdb 下使用 PC 在 .start 处启动您的程序。一次执行一个指令。仔细查看寄存器,以确保您完全理解指令的作用。如果它做了让你感到惊讶的事情,请阅读它,直到你知道为什么。不要假设任何事情。了解“step-into”与“step_over”(说真的!)。这是学习过程的一部分。这样做几个小时。是的,第一次很痛苦;当你做得更多时,它会变得容易得多。您的理解将大大提高,并且您可能会发现您的错误。
  • Tyler 在这里的回答都是关于“不要假设任何事情”,包括您假设(复数)64 位汇编只是 32 位汇编,将 32 位指令更改为 64 位。
  • 好的,找到了一个错误的假设。你确定所有的虫子都被淘汰了吗?一直使用调试器,直到您了解所有程序步骤在做什么。它的你的教育。
  • ...如果您真的想了解汇编程序,我建议您从头到尾阅读描述 x86 处理器的 Intel 手册,然后尝试使用这些知识。看这里:intel.com/content/www/us/en/processors/… 是的,很多。欢迎来到教育。 (是的,我已经完成了我刚刚向您推荐的内容。花了我一段时间。它们写得很好。)

标签: assembly


【解决方案1】:

看起来您使用 1 作为系统调用号,但it seems 它实际上是 60。显然,您不能假设系统调用号从 32 位 linux 到 64 位不一样。

经过进一步检查,似乎还有一些问题。

  • 您不要在 64 位的堆栈上传递参数(除非您有太多的参数不适合给定的 regs。查找 linux 64 位调用约定)
  • 在 main 中,您压入 2 个 dword,但在 power 中,您从堆栈中取出 2 个 qword。

您使用movq 访问内存的所有位置都可能无法按预期工作,因为这些访问是针对双字的。您在无意中读取或写入数字的高 32 位。

【讨论】:

  • 您好,感谢您的回答。不幸的是,程序仍然挂起:(
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-02-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-03-05
相关资源
最近更新 更多