gpt4 book ai didi

linux - 扫描一个整数并在 NASM 中打印区间 (1, integer)

转载 作者:塔克拉玛干 更新时间:2023-11-02 23:33:30 24 4
gpt4 key购买 nike

我正在尝试从 Linux Ubuntu 16.04 x64 学习汇编语言。现在我有以下问题:- 扫描一个整数 n 并打印从 1 到 n 的数字。

对于 n = 5,我应该有 1 2 3 4 5。我试着用 scanf 和 printf 来做,但在我输入数字后,它退出了。

代码是:

;nasm -felf64 code.asm && gcc code.o && ./a.out

SECTION .data
message1: db "Enter the number: ",0
message1Len: equ $-message1
message2: db "The numbers are:", 0
formatin: db "%d",0
formatout: db "%d",10,0 ; newline, nul
integer: times 4 db 0 ; 32-bits integer = 4 bytes

SECTION .text
global main
extern scanf
extern printf

main:

mov eax, 4
mov ebx, 1
mov ecx, message1
mov edx, message1Len
int 80h

mov rdi, formatin
mov rsi, integer
mov al, 0
call scanf
int 80h

mov rax, integer
loop:
push rax
push formatout
call printf
add esp, 8
dec rax
jnz loop

mov rax,0

ret

我知道在这个循环中我会得到反向输出 (5 4 3 2 1 0),但我不知道如何设置条件。

我使用的命令如下:

nasm -felf64 code.asm && gcc code.o && ./a.out

你能帮我找出我哪里出错了吗?

最佳答案

有几个问题:
1. printf 的参数,如评论中所述。在 x86-64 中,前几个参数是在寄存器中传递的。
2. printf不保留eax的值。
3.堆栈错位。
4.使用rbx不保存调用者的值。
5. integer 的地址被加载而不是它的值。
6. 由于printf是可变参数函数,调用前需要将eax设为0。
7. 调用 scanf 后虚假的 int 80h

我将重复整个函数以显示上下文中的必要更改。

main:
push rbx ; This fixes problems 3 and 4.

mov eax, 4
mov ebx, 1
mov ecx, message1
mov edx, message1Len
int 80h

mov rdi, formatin
mov rsi, integer
mov al, 0
call scanf

mov ebx, [integer] ; fix problems 2 and 5
loop:
mov rdi, formatout ; fix problem 1
mov esi, ebx
xor eax, eax ; fix problem 6
call printf
dec ebx
jnz loop

pop rbx ; restore caller's value
mov rax,0

ret

附言要使其向上计数而不是向下计数,请像这样更改循环:

    mov ebx, 1
loop:
<call printf>
inc ebx
cmp ebx, [integer]
jle loop

关于linux - 扫描一个整数并在 NASM 中打印区间 (1, integer),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47382206/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com