我的代码以count
作为输入来获取count
个数字并存储在数组中
代码: 初始化消息
section .data
msg db "Enter count"
msgl equ $-msg
msg1 db "Start Entering numbers"
msg1l equ $-msg1
声明count
和array
以及宏以获取输入和输出
section .bss
count resb 1
arr resw 100;Maximum size 100 word
%macro general 4
mov rax,%1
mov rdi,%2
mov rsi,%3
mov rdx,%4
syscall
%endmacro
主要功能
section .text
global _start
_start:
general 1,1,msg,msgl ;Enter a count display message
general 0,0,count,1 ;Take count input
general 1,1,count,1 ;Display that count
sub byte[count],30h ;Convert Ascii to number
mov rcx,[count] ;Store count to rcx
general 1,1,msg1,msg1l ;Display message
mov rbx,arr ;let rbx store starting address of arr
again:
general 0,0,rbx,2 ;Take number as input
inc rbx ;go to next address
dec rcx ;decrement counter
jnz again ;jump until counter is not zero
;general 1,1,msg,msgl
general 60,0,0,0 ;Exit
输出
Enter count2
2Start Entering numbers3
1
1
1
1
2
3
3
3
3
3
3
3
Dosen&#t; t out of loop。 不知道为什么。
答案 0 :(得分:1)
mov rcx,[count] ;Store count to rcx
这会从计数中加载 8 字节。但是,您只为计数(count resb 1
)保留了一个。其余的来自下一个变量arr。如果有价值观,你会得到一个完全错误的rcx
。将行更改为
movzx rcx, byte [count] ;Store count to rcx
System V AMD64 ABI calling convention定义RCX
作为来电者保存。这也适用于syscall
。我建议改变宏:
%macro general 4
push rcx
mov rax,%1
mov rdi,%2
mov rsi,%3
mov rdx,%4
syscall
pop rcx
%endmacro
系统调用SYS_READ(RAX
= 0)导致您可能从scanf
发出同样的问题。如果您没有读取所有字符,则输入缓冲区(STDIN)包含将由下一个SYS_READ读取的垃圾。如果只读取一个字符(general 0,0,count,1 ;Take count input
),则STDIN以任何方式包含按下ENTER键的LF字符。您必须清空STDIN缓冲区。如果您不想管道输入,可以使用IOCTL函数:
flush: ; http://stackoverflow.com/a/23040860/3512216
push rcx
; 32 bit Linux
; mov eax,54 ; kernel function SYS_IOCTL
; mov ebx,0 ; EBX=0: STDIN
; mov ecx,0x540B ; ECX=0x540B: TCFLSH
; xor edx, edx ; EDX=0: TCIFLUSH
; int 0x80 ; sys_call
mov eax, 16 ; kernel function SYS_IOCTL
xor edi, edi ; RDI=0: STDIN
mov esi, 0x540B ; RSI=0x540B: TCFLSH
xor edx, edx ; RDX=0: TCIFLUSH
syscall ; sys_call
pop rcx
ret
这是纠正的整个群体:
section .data
msg db "Enter count "
msgl equ $-msg
msg1 db "Start Entering numbers",10
msg1l equ $-msg1
fmt: db `rax=%lu rbx=%lu rcx=%lu rdx=%lu\n`,0
section .bss
count resb 1
dummy resb 1
arr resw 100;Maximum size 100 word
%macro general 4
push rcx
mov rax,%1
mov rdi,%2
mov rsi,%3
mov rdx,%4
syscall
pop rcx
%endmacro
section .text
flush: ; http://stackoverflow.com/a/23040860/3512216
push rcx
; 32 bit Linux
; mov eax,54 ; kernel function SYS_IOCTL
; mov ebx,0 ; EBX=0: STDIN
; mov ecx,0x540B ; ECX=0x540B: TCFLSH
; xor edx, edx ; EDX=0: TCIFLUSH
; int 0x80 ; sys_call
mov eax, 16 ; kernel function SYS_IOCTL
xor edi, edi ; RDI=0: STDIN
mov esi, 0x540B ; RSI=0x540B: TCFLSH
xor edx, edx ; RDX=0: TCIFLUSH
syscall ; sys_call
pop rcx
ret
global main
main:
general 1,1,msg,msgl ; Enter a count display message
general 0,0,count,1 ; Take count input
call flush ; flush STDIN
general 1,1,count,1 ; Display that count
sub byte[count],30h ; Convert Ascii to number
movzx rcx, byte [count] ; Store count to rcx
general 1,1,msg1,msg1l ; Display message
mov rbx,arr ; let rbx store starting address of arr
again:
general 0,0,rbx,2 ; Take number as input
call flush
inc rbx ; go to next address
dec rcx ; decrement counter
jnz again ; jump until counter is not zero
;general 1,1,msg,msgl
general 60,0,0,0 ; Exit