【发布时间】:2015-01-19 02:45:30
【问题描述】:
所以我正在学习使用 NASM 的 x86 汇编,并且我正在尝试制作一个打印出整数的简单函数。我的代码...
print_integer: ; Integer input stored in eax
mov ecx, 10
print_integer_loop:
mov edx, 0
div ecx ; eax /= 10 | edx = eax % 10
or edx, 0x30 ; Convert 0-9 to ‘0’-‘9’
push edx ; Push remaineder to stack
mov eax, 4 ; sys_write
mov ebx, 1 ; STDOUT
mov ecx, esp ; Top of Stack to ecx
mov edx, 1 ; Print 1 byte
int 0x80 ; syscall
pop edx
cmp eax, 0 ; Compare quotient to 0
jnz print_integer_loop
_main:
mov eax, 4251
call print_integer
mov eax, 1 ; ‘Exit’ System call
mov ebx, 0 ; Exit with error code 0
int 0x80 ; syscall
当我运行此代码时,没有任何反应。它只是结束而不打印任何东西。我查看了所有类似的主题,但我发现没有一个有用。我不确定出了什么问题,所以任何见解都会很棒。
编辑:我将 NASM 更新为更新的版本,因此我可以使用 x86_64 系统调用。代码如下
print_integer: ; Assume integers is in r15
push 0x0a ; Push endline character
mov r14, 1 ; Setup counter for printing
stack_loop:
mov rax, r15 ; Move r15 to rax for divison
xor rdx, rdx ; Avoids error
mov rcx, 10
div rcx ; rax = rdx:rax / rcx | rdx = rdx:rax % rcx
add rdx, '0' ; Convert 0-9 to ‘0’-‘9’
push rdx ; Push remainder to stack
mov r15, rax ; Move quotient to r15 register
inc r14 ; Counter + 1
cmp r15, 0 ; Compare quotient to 0
jne stack_loop ; If not zero, loop
; Characters are now on stack in reverse order
print_loop:
mov rsi, rsp ; Put remainder in rsi
mov rdx, 1 ; Print 1 char (length)
mov rax, 0x2000004 ; System call write
mov rdi, 1 ; Standard output, number of bytes
syscall ; Invoke kernal
dec r14 ; Counter - 1
pop r15 ; Remove off top of stack
cmp r14, 0
jne print_loop
ret
希望这对将来的某人有所帮助。这可能不是最好的方法,但它是一种方法。
【问题讨论】:
-
这个打印方法似乎与堆栈或其他东西混淆了,因为如果我将一个新值加载到 r15 并尝试再次打印它会打印出一些垃圾,关于它为什么会发生的任何想法?
-
你能把你的代码发给我吗?我可以看看它,希望能够提供帮助。这是我第一次遇到这个问题。
-
您可以在此处找到代码:pastebin.com/jcpMhTQE 似乎与堆栈 (rbp) 混淆了,哦,我正在使用 x86_64 程序集在 mac os x 上运行并使用 NASM 生成二进制文件。
-
更新:没关系,这是我这边的错误,我刚开始使用 ASM 并使用 gcc 编译器的输出作为参考,开始时的 mov rsp,rsb 行搞砸了指向我的堆栈的指针。现在似乎运行良好。
-
相关:How do I print an integer in Assembly Level Programming without printf from the c library? 在堆栈上创建一个字符串,因此您可以高效地执行一个
syscall。
标签: assembly printing x86 integer