问题描述
我正在接受来自用户输入两次,并比较输入。如果它们是相同的,该程序退出。如果不是,它重新打印从第一次输入,并等待用户键入的东西。如果是相同的,同样的事情发生前。如果没有,同样的事情发生之前。
I am working to take input from a user twice, and compare the input. If they are the same, the program exits. If not, it reprints the input from the first time, and waits for the user to type something. If it is the same, the same thing as before occurs. If not, the same thing as before occurs.
输入和循环是没问题的。主要的问题是我从程序获得的结果。我下面是我在做什么codewise:
Input and looping is not the problem. The main problem is the result I am getting from the program. My following is what I am doing codewise:
%include "system.inc"
section .data
greet: db 'Hello!', 0Ah, 'Please enter a word or character:', 0Ah
greetL: equ $-greet ;length of string
inform: db 'I will now repeat this until you type it back to me.', 0Ah
informL: equ $-inform
finish: db 'Good bye!', 0Ah
finishL: equ $-finish
newline: db 0Ah
newlineL: equ $-newline
section .bss
input: resb 40 ;first input buffer
check: resb 40 ;second input buffer
section .text
global _start
_start:
greeting:
mov eax, 4
mov ebx, 1
mov ecx, greet
mov edx, greetL %include "system.inc"
section .data
greet: db 'Hello!', 0Ah, 'Please enter a word or character:', 0Ah
greetL: equ $-greet ;length of string
inform: db 'I will now repeat this until you type it back to me.', 0Ah
informL: equ $-inform
finish: db 'Good bye!', 0Ah
finishL: equ $-finish
newline: db 0Ah
newlineL: db $-newline
section .bss
input: resb 40 ;first input buffer
check: resb 40 ;second input buffer
section .text
global _start
_start:
greeting:
mov eax, 4
mov ebx, 1
mov ecx, greet
mov edx, greetL
sys.write
getword:
mov eax, 3
mov ebx, 0
mov ecx, input
mov edx, 40
sys.read
sub eax, 1 ;remove the newline
push eax ;store length for later
instruct:
mov eax, 4
mov ebx, 1
mov ecx, inform
mov edx, informL
sys.write
pop edx ;pop length into edx
mov ecx, edx ;copy into ecx
push ecx ;store ecx again (needed multiple times)
mov eax, 4
mov ebx, 1
mov ecx, input
sys.write
mov eax, 4 ;print newline
mov ebx, 1
mov ecx, newline
mov edx, newlineL
sys.write
mov eax, 3 ;get the user's word
mov ebx, 0
mov ecx, check
mov edx, 40
sys.read
xor eax, eax
checker:
mov ebx, check
mov ecx, input
cmp ebx, ecx ;see if input was the same as before
jne loop ;if not the same go to input again
je done ;else go to the end
pop edx
mov ecx, edx
push ecx
mov eax, 4
mov ebx, 1
mov ecx, check
sys.write ;repeat the word
mov eax, 4
mov ebx, 1
mov ecx, newline
mov edx, newlineL
sys.write
loop:
mov eax, 3 ;replace new input with old
mov ebx, 0
mov ecx, check
mov edx, 40
sys.read
jmp checker
done:
mov eax, 1
mov ebx, 0
sys.exit
sys.write
getword:
mov eax, 3
mov ebx, 0
mov ecx, input
mov edx, 40
sys.read
我的结果是现在:EDITED
My result is now: EDITED
Hello!
Please enter a word or character:
Nick
I will now repeat this until you type it back to me.
Nick
(I input) Magerko
(I get) M
(I input)Nick
(I get)
(I input)Nick
(I get)
EDITED
EDITED
和这样下去。如打算在code以上我检查不工作,我最终没有连得程序打印什么,但一个换行符。有没有道理呢?
And this continues. My checks do not work as intended in the code above, and I eventually don't even get the program to print anything but a newline. Is there a reason for this?
感谢。
推荐答案
除了什么@Joshua被指出的是,你不正确的比较的字符串。
Apart from what @Joshua is pointing out, you're not comparing your strings correctly.
checker:
mov ebx, check ; Moves the *address* of check into ebx
mov ecx, input ; Similarly for input
cmp ebx, ecx ; Checks if the addresses are the same (they never are)
首先,当你有例如标签DD 1234
在你的数据段 MOV EAX,标签
将移动的的地址的标签
到 EAX
,而 MOV EAX,[标签]
将移动的的内容的保存在标签
(在这种情况下,1234)为 EAX
。
Firstly, when you have e.g. label dd 1234
in your data segment mov eax, label
will move the address of label
to eax
while mov eax, [label]
will move the contents stored at label
(in this case 1234) into eax
.
请注意,在上面的例子中我特意用一个32位的变量,以便它巧妙地融入 EAX
。如果你正在使用的字节大小的变量(如ASCII字符)例如 mybyte分贝0xFE的
你要么必须使用字节大小的寄存器(人
,啊
, DH
等)或使用零/符号,此举扩展运算codeS: MOVZX EAX,字节[ mybyte]
将设置EAX为254,而 MOVSX EAX,字节[mybyte]
将设置EAX为-2( 0xfffffffe
)。
Note that in the above example I deliberately used a 32-bit variable so that it would fit neatly into eax
. If you're using byte sized variables (like ascii characters) e.g. mybyte db 0xfe
you'll either have to use byte sized register (al
, ah
, dh
etc.) or use the move with zero/sign extend opcodes: movzx eax, byte [mybyte]
will set eax to 254, while movsx eax, byte [mybyte]
will set eax to -2 (0xfffffffe
).
您还需要通过字符串的字符比较做一个字符。 input_len 和 check_len - 假设你保存读字符串长度(即错误,你真的应该检查负的返回值) >这可能看起来像:
You also need to do a character by character comparison of the strings. Assuming you save the read string length (you really should be checking for negative return values - meaning errors) in
input_len
and check_len
it could look something like:
mov eax, [input_len]
cmp eax, [check_len]
jne loop ; Strings of different length, do loop again
mov ebx, check
mov ecx, input
.checkloop:
mov dl, [ebx] ; Read a character from check
cmp dl, [ecx] ; Equal to the character from input?
jne loop ; Nope, jump to `loop`
inc ebx ; Move ebx to point at next character in check
inc ecx ; and ecx to next character in input
dec eax ; one less character to check
jnz .checkloop ; done?
; the strings are equal if we reach this point in the code
jmp done
如果您有兴趣的指令较少这样做的另一种方式查找
代表CMPSB
。
If you're interested in another way of doing this in fewer instructions look up
rep cmpsb
.
有在$ C $其他一些问题ç立即与
检查
code以下。在流行EDX
指令(和code以下,下降到循环
标签)将不被执行的你总是跳跃要么循环
或完成
。
There are a few other problems in the code immediately following your
checker
code. The pop edx
instruction (and the code following, down to the loop
label) will not be execute as you're always jumping either to loop
or done
.
jne loop ;if not the same go to input again
je done ;else go to the end
pop edx ; Will never be reached!
你得到一些奇怪的字符的原因是从
newlineL:DB $ -newline
这应该是 EQU
代替的分贝
或你应该替换 MOV EDX,newlineL
与 MOVZX EDX,字节[newlineL]
。由于 newlineL
不像其他 * L
名称指的是一个变量,而不是一个恒定的 EQU
MOV EDX,newlineL
将使用 newlineL
变量的地址字节到数写,当你希望它是1。
The reason you're getting funny characters is from
newlineL: db $-newline
This should be equ
instead of db
or you should replace mov edx, newlineL
with movzx edx, byte [newlineL]
. Since newlineL
unlike the other *L
names refers to a variable and not a constant equ
mov edx, newlineL
will use the address of the newlineL
variable as the number of bytes to write, when you wanted it to be 1.
这篇关于86 NASM大会 - 输入问题的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!