86 NASM大会 - 输入问题 [英] x86 NASM Assembly - Problems with Input

查看:182
本文介绍了86 NASM大会 - 输入问题的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在接受来自用户输入两次,并比较输入。如果它们是相同的,该程序退出。如果不是,它重新打印从第一次输入,并等待用户键入的东西。如果是相同的,同样的事情发生前。如果没有,同样的事情发生之前。

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大会 - 输入问题的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆