我发誓我今天已经阅读了20多页,从NASM的手册到大学的指南,到维基百科,以及介于两者之间的所有内容但是我无法绕过这个,我写了一个程序来比较用户输入使用0或1然后根据它行动(我应该使用数组,一旦我在程序集中得到它们的挂起),但现在这样做。
问题是,我的检查永远不会工作,他们总是直接找到错误的标签,我看着x86 NASM Assembly - Problems with Input看起来很相似,但它不太相同,我真的不喜欢不需要存储用户的输入,只需检查它是什么并对其作出反应。
这是我的代码的缩小版本,它应该在输入两个连续的0之后退出,显然我无法测试它,因为我无法弄清楚用户输入了什么。
我很抱歉,如果这是一个愚蠢的问题,但本周大会已经让我最好。
; constants
section .data
lblZero: db 'Zero';
lblOne: db 'One ';
lblNumLength: db 0x4;
tmp: db 0;
; code
section .text
global _start
; linker needs this, 'main'
_start:
loop:
; user was already prompted for a single digit
; store user's input ; read
mov rax, 0 ;
mov rbx, 19 ;
mov rcx, tmp ;
mov rdx, 10 ;
syscall
; series of IFs
cmp rcx, 0 ; is input 0? 00 exits the program
je isZero
cmp rcx, 1 ; is input 1?
je isOne
jmp exit
; user typed 0
isZero:
inc rcx ; flag for 0
cmp rcx, 2 ; checking if this is the 2nd zero
je exit ; if so, we are outta here
mov rsi, lblZero ;
mov rcx, -1 ;
jmp print ;
; user typed 1
isOne:
mov rsi, lblOne ;
mov rcx, -1 ;
jmp print ;
; prints the string into the screen ; sys_write
print:
mov rax, 1 ;
mov rdi, 1 ;
mov rdx, lblNumLength ;
syscall
jmp loop
; displays an error message
err:
; sys_write, not relevant to the Q
syscall
jmp loop
; shutsdown program ; sys_write ; sys_exit
exit:
; not relevant to the Q, code always ends here
我在这里读到http://www.cin.ufpe.br/~if817/arquivos/asmtut/index.html#stack输入不是真正的int,而是一个字符,所以我尝试创建只存储'1'或'0'的变量,但似乎没什么可做的。
我是大会的新手,所以如果我在这里真的很蠢,如果你指出它,我将不胜感激。
答案 0 :(得分:2)
假设你试图在64位AMD64 linux上运行它,你需要确保使用正确的方法将参数传递给内核(调用约定)。
对于linux / x64上的64位应用程序,它如下:
此外,Paul R的回答也是正确的。 ASCII表示'0'不是十进制零。另一个问题是默认情况下stdin在缓冲模式下运行,因此在按Enter键之前,您实际上不会获得任何数据。下面的代码将两个字节读入tmp缓冲区(由rsi指向)并将第一个字节与ascii-zero进行比较。第二个字节是我们并不特别感兴趣的换行符。
; constants
section .data
lblZero: db 'Not zero, try again', 0xa;
tmp: db 0,0;
; code
section .text
BITS 64
global _start
_start:
mov rax, 0 ; sys_read(int fd, void *ptr, int count)
mov rdi, 0 ; 0 = stdin
mov rsi, tmp ; @ tmp
mov rdx, 2 ; 2 bytes (one for our number, another to store newline)
syscall
cmp byte[rsi], '0' ; is input '0' (or decimal 48) ?
je done
mov rax, 1 ; sys_write(int fd, void *ptr, int count)
mov rdi, 1 ; 1 = stdout
mov rsi, lblZero ; @lblZero
mov rdx, 20 ; 20 bytes
syscall
jmp _start
done:
mov rax, 60 ; sys_exit
mov rdi, 0
syscall
答案 1 :(得分:1)
您需要比较字符,而不是整数值。变化:
cmp rcx,0
到
cmp byte [rcx],'0'
与1比较同上。