【发布时间】:2018-09-10 10:18:39
【问题描述】:
我正在尝试创建一个将为我打印十进制数字的宏。我的想法是将数字除以 10,将余数转换为 ASCII 并将其推入堆栈,直到比率为 0。然后我一个接一个地打印数字,但由于某种原因,我得到一个“分段错误”。
我使用的是 Linux、nasm 和 x86_64 处理器。
%macro printInt 1
mov rax, %1
mov rbx, 0
%%loop1: ;Convert all digits to ascii
inc rbx ;Count of the digits in number
mov rdx, 0
div rax
add rdx, 48 ;Convert remainder to ascii
push rdx ;Push remainder into stack
cmp rax, 0 ;Compare ratio to 0
jne %%loop1
%%loop2: ;Print the number digit by digit
dec rbx
mov rax, 1 ;Sys_Write
mov rdi, 1 ;STDOUT
pop rsi ;Pop digit
mov rdx, 1
syscall
cmp rbx, 0
jne %%loop2
%endmacro
section .data
number1 db 123
section .text
global _start
_start:
printInt number1
mov rax, 60
mov rdi, 0
syscall
任何帮助表示赞赏,在此先感谢!
【问题讨论】:
-
idownvotedbecau.se/nodebugging (这是提示“使用调试器”来弄清楚,段错误的原因是什么)......第二个提示是:为什么是宏?我看不出有什么理由把它写成宏而不是标准的子例程(但我有很多理由不把它写成宏,这样使用的宏会使调试和代码审查变得更加困难)
-
我不知道如何使用 gdu 调试器,我使用了一个宏,因为我猜它让我想起了函数。你能为我推荐一个好的调试器吗?由于某种原因,我似乎无法安装 DDD 或 Insight
-
我个人使用github.com/eteran/edb-debugger(从源代码编译,但我认为最近一些发行版可能已经在存储库中,尝试搜索“edb-debugger”)。它正在不断发展,到目前为止我不建议将其用于大型项目的调试,但仅用于学习 x86 汇编的基础知识,它应该可以很好地工作,它具有所有基本工具。宏不是函数,宏在您使用它的任何地方都会复制指令。使用适当的功能,即在某处编写代码一次,然后从其他代码中
call。 -
在学习 x86 汇编的基础知识时,你应该零需要/使用宏,毕竟这些是汇编指令,而不是使它成为最终二进制文件的东西,所以你可以用宏编写的所有东西,你也可以用纯汇编编写,一开始所有可能闻起来像“宏可以在这里为我节省很多打字”的东西实际上意味着“我应该更好地重组我的汇编”。有时宏可以极大地帮助保持源代码更易于阅读/维护或提高性能,但在您学习基础知识时,这些都不应该出现。
标签: linux assembly x86 nasm x86-64