1

它需要允许输入一个两位数的数字,用于指示名称被打印了多少次。我不知道如何分隔第二个数字并检查它以确保它在 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       

提前致谢!

4

1 回答 1

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

然后,下一个错误是您最近加载counteax,然后将加载到的最低 8 位乘以count10 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 %bl之间进行 o 有符号相乘,并将结果存储在. 所以上面的代码可以改成这样:alblax

    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

然后,您可以像检查第一个字符一样检查第二个字符:

    pop %eax        // pop eax from stack

    incl %eax

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

    sub $0x30, %bl  // 0 <= bl <= 9

    add %bl, max    // 0 <= max <= 99

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

于 2013-03-10T01:06:40.967 回答