【发布时间】: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