【问题标题】:Is there a way to repeat this one more time?有没有办法再重复一次?
【发布时间】:2021-08-29 21:45:48
【问题描述】:

我用 nasm x86 汇编代码编写 +-_ ,其中空白是用户输入。现在我已经有了它,但我需要它来阅读下一行并在那里做。我是汇编新手,我不想使用循环或指针或任何东西。也许是时代的一种方式? 这是我的代码:

segment .data 
    newline db 0xA, 0xD
    newlinelen equ $-newline
    
    segment .bss
    
       num1 resb 2
       num2 resb 2
       num3 resb 2
       ;num4 resb 2
       ;num5 resb 2
       ;num6 resb 2
       res resb 1   
       ;res2 resb 1
    
    section .text
       global main    ;must be declared for using gcc
        
    main:             ;tell linker entry point
    
    ;reading num 1
       mov eax, 3
       mov ebx, 0  
       mov ecx, num1 
       mov edx, 2
       int 0x80  
    
    ;reading num 2
       mov eax, 3
       mov ebx, 0
       mov ecx, num2 
       mov edx, 2
       int 0x80   
       
     ;reading num 3
       mov eax, 3
       mov ebx, 0  
       mov ecx, num3 
       mov edx, 2
       int 0x80    
      ;new line for next equation 
       mov edx, newline 
       mov ecx, newlinelen
       mov ebx, 1
       mov eax, 4
       int 0x80  
    
    
       ; moving the first number to eax register and second number to ebx
       ; and subtracting ascii '0' to convert it into a decimal number
        
       mov eax, [num1]
       sub eax, '0'
       mov ebx, [num2]
       sub ebx, '0'
       mov ecx, [num3] 
       sub ecx, '0'
    
       ; add ebx to eax
       add eax, ebx
       ; add '0' to to convert the sum from decimal to ASCII
       add eax, '0'
    
       ; storing the sum in memory location res
       mov [res], eax
       ;subtract ecx from eax
       sub eax, ecx
       mov [res], eax
       
    
       ; print the sum 
       mov eax, 4       
       mov ebx, 1
       mov ecx, res         
       mov edx, 1   
       int 0x80
    
    
    exit:    
       int 0x80

我的输入是 1+2-1,输出是 2,这是正确的。我不需要在 4 以上的任何数字或负数上使用它。 我试过用数字 4、5、6 重复整个过程,但结果只是给了我一个空白的 ascii 字符,这是我得到的最接近结果的字符。

;;new equation?
   
   ;reading num 4
   mov eax, 3
   mov ebx, 0  
   mov ecx, num4 
   mov edx, 2
   int 0x80  

;reading num 5
   mov eax, 3
   mov ebx, 0
   mov ecx, num5 
   mov edx, 2
   int 0x80   
   
 ;reading num 6
   mov eax, 3
   mov ebx, 0  
   mov ecx, num6 
   mov edx, 2
   int 0x80


   ; moving the first number to eax register and second number to ebx
   ; and subtracting ascii '0' to convert it into a decimal number
    
   mov eax, [num4]
   sub eax, '0'
   mov ebx, [num5]
   sub ebx, '0'
   mov ecx, [num6] 
   sub ecx, '0'

   ; add ebx to eax
   add eax, ebx
   ; add '0' to to convert the sum from decimal to ASCII
   add eax, '0'

   ; storing the sum in memory location res
   mov [res2], eax
   ;subtract ecx from eax
   sub eax, ecx
   mov [res2], eax
   

   ; print the sum 
   mov eax, 4       
   mov ebx, 1
   mov ecx, res2       
   mov edx, 1   
   int 0x80

我也试过用 AL 代替 eax,用 AH 代替另一个方程,但它不像我也不明白的那样工作。然后我还尝试制作每个字节并放入段符号 resb 1,用于 + 符号,这不起作用。我只是希望它在之后再读一行。

【问题讨论】:

    标签: assembly nasm


    【解决方案1】:
      mov edx, newline 
      mov ecx, newlinelen
    

    您已经在此处反转了寄存器。

      mov eax, [num1]
      ...
      mov [res], eax
    

    这些指令之间的所有内容都应使用字节大小的寄存器。使用ALBLCL。目前您正在覆盖不属于 res 变量的内存!

      ; add '0' to to convert the sum from decimal to ASCII
      add eax, '0'
    

    您应该先进行减法,然后再转换回 ASCII,然后使用 mov [res], al 将字符存储在 res 变量中一次。

    exit:    
       int 0x80
    

    您的出口缺少eax 寄存器中的函数号!


    有没有办法再重复一遍?

    即使您不喜欢它,循环也是可行的方法times 运算符是装配时功能。你可以把整个东西变成一个宏并让它调用两次,但是你也可以像现在这样写第二次。

    【讨论】:

    • 对于构建时间重复,您也可以使用 NASM 的预处理器 %rep 构造。
    【解决方案2】:

    我只是重复代码而不是添加值 4、5 和 6,但将它们放在更高的字符而不是更低的字符中。还为新行添加了一个读取垃圾字符。

    segment .data 
        newline db 0xA, 0xD
        newlinelen equ $-newline
        
        segment .bss
        ;defining all variables
           num1 resb 2
           num2 resb 2
           num3 resb 2
    ;variables for next equation
           num4 resb 2
           num5 resb 2
           num6 resb 2
    ;newlin for garbage character
           newlin resb 1
    ;result 1 and result 2
           res resb 1   
           res2 resb 1
        
        section .text
           global main    ;must be declared for using gcc
            
        main:             ;tell linker entry point
        
        ;reading num 1
           mov eax, 3
           mov ebx, 0  
           mov ecx, num1 
           mov edx, 2
           int 0x80  
        
        ;reading num 2
           mov eax, 3
           mov ebx, 0
           mov ecx, num2 
           mov edx, 2
           int 0x80   
           
         ;reading num 3
           mov eax, 3
           mov ebx, 0  
           mov ecx, num3 
           mov edx, 2
           int 0x80   
        
        
           ; moving the first number to eax register and second number to ebx
           ; and subtracting ascii '0' to convert it into a decimal number
            ;moving variables in lower halfs
           mov AL, [num1]
           sub AL, '0'
           mov BL, [num2]
           sub BL, '0'
           mov CL, [num3] 
           sub CL, '0'
        
           ; add ebx to eax
           add AL, BL
    
        
           ; storing the sum in memory location res
           mov [res], AL
           ;subtract ecx from eax
           sub AL, CL
           ; add '0' to to convert the sum from decimal to ASCII
           add AL, '0'
           mov [res], AL
           
        
           ; print the sum 
           mov eax, 4       
           mov ebx, 1
           mov ecx, res         
           mov edx, 1   
           int 0x80
          
          ;new line for next equation
          mov eax, 4
          mov ebx, 1
          mov ecx, newline
          mov edx, newlinelen
          int 0x80
         
          ;;new equation?
          ;;skip garbage character
           mov eax, 3
           mov ebx, 0
           mov ecx, newlin
           mov edx, 1
           int 0x80
       
       ;reading num 4
       mov eax, 3
       mov ebx, 0  
       mov ecx, num4 
       mov edx, 2
       int 0x80  
    
    ;reading num 5
       mov eax, 3
       mov ebx, 0
       mov ecx, num5 
       mov edx, 2
       int 0x80   
       
     ;reading num 6
       mov eax, 3
       mov ebx, 0  
       mov ecx, num6 
       mov edx, 2
       int 0x80
    
    
       ; moving the first number to eax register and second number to ebx
       ; and subtracting ascii '0' to convert it into a decimal number
    ;moving variables in higher halfs
       mov AH, [newlin]
       mov BH, [num4]
       sub BH, '0'
       mov CH, [num5]
       sub CH, '0'
       mov DH, [num6] 
       sub DH, '0'
    
       ; add ebx to eax
       add BH, CH
       ;subtract ecx from eax
       sub BH, DH
       ; add '0' to to convert the sum from decimal to ASCII
       add BH, '0'
       ;move ah into memory location res 2
       mov [res2], BH
       
       
    
       ; print the sum 
       mov eax, 4       
       mov ebx, 1
       mov ecx, res2       
       mov edx, 1 
       int 0x80
        
        
        exit:    
           mov eax, 1
           int 0x80
    

    【讨论】:

    • 我看到您已成功地将我的答案中的信息合并到您的新代码中。也许您可以承认这一事实并单击我答案左侧的接受标记。甚至可能因为您有权这样做而投票赞成。
    猜你喜欢
    • 1970-01-01
    • 2017-08-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-07-02
    • 1970-01-01
    • 2021-02-15
    相关资源
    最近更新 更多