x86组装2位数字键盘输入

时间:2013-03-09 23:52:42

标签: linux assembly input x86

它需要允许两位数的输入数字,用于指示打印名称的次数。我无法弄清楚如何分离第二个数字,并检查它以确保它在0x30和0x39之间。我还在其中包含0017的名称之后继续得到这个奇怪的盒子。

    .data   
    input_msg_len:  .long 26
    input_msg:  .ascii "Enter a two-digit number: "
    name:       .ascii "Michael Chabon\n"
    name_len:   .long 16
    max:        .long 0
    count:      .long 0
    tmp:        .long 0
    input_str:  .ascii "??" 

    .text               
    .global _start          
    _start:     
        mov $4, %eax    
        mov $1, %ebx
        mov $input_msg, %ecx
        mov input_msg_len, %edx
        int $0x80

        mov $3, %eax    
        mov $0, %ebx    
        mov $input_str, %ecx 
        mov $2, %edx    
        int $0x80   

        mov $input_str, %eax
        add count, %eax

            mov $input_str, %eax 
        mov (%eax), %bl 
        cmp $0x30, %bl  
        jl  _start      
        cmp $0x39, %bl  
        jg  _start  

        mov count, %eax 
        inc %eax        
        mov %eax, count 

        sub $0x30, %bl
        mov %bl, max

        mov $10, %bl    
        imul    %bl
        mov %bl, max

#Not sure how to check second char in input_str.
#Want to check it then subtract $0x30 and move to tmp before adding tmp to max.

        mov $0, %edi    
    again:
        cmp max, %edi   
        je  end     

        mov $4, %eax    
        mov $1, %ebx    
        mov $name, %ecx
        mov name_len, %edx
        int $0x80       

        inc %edi        
jmp again       


    end:
        mov $1, %eax    
        int $0x80       

提前致谢!

1 个答案:

答案 0 :(得分:0)

您的代码中存在一些错误。

下面,该块的2个第一行是多余的,因为mov $input_str, %eax无论如何都会覆盖eax

    mov $input_str, %eax
    add count, %eax

    mov $input_str, %eax

然后在这里,将count加载到eax这里是没有意义的:

    mov count, %eax 
    inc %eax        
    mov %eax, count

你可以用更短更清晰的方式做到这一点:

    incl count

然后,下一个错误是您最近将count加载到eax,然后将加载到count的{​​{1}}的最低8位乘以10,代码:

al

所以,根据我的直觉,你不想 mov (%eax), %bl // bl = first character cmp $0x30, %bl jl _start cmp $0x39, %bl jg _start mov count, %eax // eax = count inc %eax // eax++ mov %eax, count // count = eax sub $0x30, %bl // 0 <= bl <= 9 mov %bl, max // max = bl <- you lose this value in the next mov %bl, max mov $10, %bl // bl = 10 imul %bl // ax = 10 * and(count, 0xff) // ax = al*bl (signed multiply) mov %bl, max // max = 10 <- here you overwrite the value of max with 10 ,而是ax = 10 * and(count, 0xff)10 * (first number)imul %blal之间进行了对齐,并将结果存储在bl中。所以上面的代码可以改成这样的代码:

ax

然后,您可以与第一个字符类似地检查第二个字符:

    mov (%eax), %bl  // bl = first character
    cmp $0x30, %bl  
    jl  _start      
    cmp $0x39, %bl  
    jg  _start  

    incl count

    pushl %eax      // push eax to stack

    sub $0x30, %bl  // 0 <= bl <= 9
    mov $10, %al    // al = 10
    imul     %bl    // ax = 10 * bl (signed multiply)
    mov %al, max    // 0 <= max <= 90

我强烈建议您学习使用一些调试器。 gdb有几个前端,我认为根据我的经验,ddd效果最好。 gdbtui也很方便。