nasm 无限循环与 rcx
nasm infinite loop with rcx
我有代码将 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
OUTPUT
Enter count2
2Start Entering numbers3
1
1
1
1
2
3
3
3
3
3
3
3
不要跳出循环。
不知道为什么。
mov rcx,[count] ;Store count to rcx
这会从计数中加载 8 个字节。但是,您只为计数 (count resb 1
) 保留了 one。剩下的来自下一个变量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: ;
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: ;
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
我有代码将 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
OUTPUT
Enter count2
2Start Entering numbers3
1
1
1
1
2
3
3
3
3
3
3
3
不要跳出循环。 不知道为什么。
mov rcx,[count] ;Store count to rcx
这会从计数中加载 8 个字节。但是,您只为计数 (
count resb 1
) 保留了 one。剩下的来自下一个变量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: ; 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: ;
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