2017-10-28 185 views
1

下面的代码假设有显示如果哪个数字更大或者它们是否相等和总和,但我得到的只是总和,如果我删除了总和部的第一部分,其中显示的数字是否等于x86显示输出的其余部分(内联)

section .rodata                             
      prompt1 db "Enter an integer: ",0 ; 0 is null character                 
      prompt2 db "Enter another integer: ",0                      
     num_format db "%ld",0                           
      format_str1 db "The greater of %ld and %ld is %ld.",10,0 ; 10 is LF               
      format_str2 db "The sum of %ld and %ld is %ld.",10,0 ; 10 is LF                
      equalprompt db "%ld and %ld are equal.",10,0 ; 10 is LF                  

      section .text                             
      global main    ; main and _start are both valid entry points               
      extern printf, scanf  ; these will be linked in from glibc i                 

      main:  
      ; prologue                              
      push rbp   ; save base pointer to the stack                   
      mov  rbp, rsp  ; base pointer = stack pointer                    
      sub  rsp, 16  ; make room for two long integers on the stack                
      push rbx   ; push callee saved registers onto the stack                
      push r12   ; push automatically decrements stack pointer                
      push r13                              
      push r14                              
      push r15                              
      pushfq    ; push register flags onto the stack                  

      ; prompt for first integer                          
      mov rdi, dword prompt1 ; double word is 4 bytes; a word is 2 bytes              
             ; rdi = 32-bit address of prompt1                 
      xor rax, rax    ; rax is return value register - zero it out              
      call printf    ; call the C function from glibc                 

      ; read first integer                           
      lea rsi, [rbp-8]   ; load effective address - this instruction              
             ; computes the address 8 bytes above the               
             ; base pointer - the integer read by scanf               

      mov rdi, dword num_format ;                         
      xor rax, rax    ; zero out return value register                 
      call scanf     ; call C function                     
             ; scanf reads the input as an integer                

      ; prompt for second integer                          
      mov rdi, dword prompt2                          
      xor rax, rax                             
      call printf                             

      ; read second integer                           
      lea rsi, [rbp-16]                           
      mov rdi, dword num_format                         
      xor rax, rax                             
      call scanf                             

      ; determine if num2 (second integer) is greater than num1 (first integer)              
      xor  rbx, rbx  ; RBX = 0x0                        
      mov  rax, [rbp-16] ; RAX = num2 ; load rax with value at rdb-16                
      cmp  rax, [rbp-8] ; compute (num1) - (num2) and set condition codes               
      ; in machine status word register based on result                    
      jl  lessthan  ; jump if num1 <= num2                      
      je  equal                             

     ; num1 > num2                             
      mov  rdi, dword format_str1                         
      mov  rsi, [rbp-8]  ; num1 
      mov  rdx, [rbp-16] ; num2                         
      mov  rcx, [rbp-16] ; greater of the two                     
     ;mov  rcx, 0                             
      ; add  rcx, rsi                            
      ; add  rcx, rdx                            
      ; xor  rax, rax                            
      jmp sum                               

      lessthan:                              
      ; num1 < num2                             
      mov  rdi, dword format_str1                         
      mov  rsi, [rbp-8] ; num1                         
      mov  rdx, [rbp-16] ; num2                         
      mov  rcx, [rbp-8] ; greater of the two                      
     ;mov  rcx, 0                             
     ;add  rcx, rsi                            
      ; add  rcx, rdx                            
      ; xor  rax, rax                            
     jmp  sum                              

     equal:                               
     mov  rdi, dword equalprompt                         
     mov  rsi, [rbp-8] ; num1                         
     mov  rdx, [rbp-16] ; num2                         
     jmp  sum                              

     sum:                               

     mov rdi, dword num_format ;                         
     mov  rdi, dword format_str2                         
     mov  rsi, rsi ; num1                          
     mov  rdx, rdx ; num2                          
     mov  rcx, 0                             
     add  rcx, rsi                            
     add  rcx, rdx                            
     jmp exit                              

     exit:                               
     call printf                             
     ; epilogue                              
     popfq                               
     pop  r15                              
     pop  r14                              
     pop  r13                              
     pop  r12                              
     pop  rbx                              
     add  rsp, 16  ; set back the stack level                    
     leave                               
     ret  

示例输出是这样的:

Enter an integer: 7                               
Enter another integer: 3                             
The sum of 7 and 3 is 10 
+0

请删除行号,以便其他用户可以组装您的代码并将其插入调试器。 – fuz

+1

线路120上的'call printf'只能执行一个或另一个。我认为你应该在第109行添加另一个'call printf'。 –

+0

你不需要在函数中保存FLAGS,它们像'rcx','rdx'等一样被调用。此外,你不需要推动/弹出你永远不会碰到的寄存器(比如'r12')。这只是一个浪费的指令,就像'jmp exit' /'exit:'一样。你不需要跳过空行;反正总是执行下一条指令。 –

回答

1
mov rax, [rbp-16] ; RAX = num2 ; load rax with value at rdb-6 
cmp rax, [rbp-8] ; compute (num1) - (num2) and set condition code 
jl lessthan  ; jump if num1 <= num2 
je equal 

从这个cmp开始的评论大多是错误的(反向)!
什么cmp计算是RAX - [rbp-8],所以num2 - num1
您的jl lessthan跳转如果num2 < num1。 幸运的是,在后面的代码片段中填充两者中较大者的代码是正确的。


当代码到达标签总和,你立即摧毁你精心设置了RDI寄存器开始。您应该首先发出call printf以显示显示较大数字的第一行结果。此后,您可以设置显示总和的第二行结果。


为什么不简化代码呢?您可以从num1中的RSInum2中的RDX开始,然后比较这些寄存器,而不是在RAX中进行,后来不得不重复加载这些寄存器。
也不要害怕做一些看似无用的操作,如果这样做可以减少程序中分支的数量。看看下一代码如何加载RDI,并可能以后需要重新加载其他值?加载RCX也可能需要重新加载。

mov  rsi, [rbp-8] ; num1 
    mov  rdx, [rbp-16] ; num2    
    cmp  rsi, rdx 
    mov  rdi, dword equalprompt        
    je  sum 
    mov  rdi, dword format_str1        
    mov  rcx, rsi  ; num1 is greater of the two 
    jg  sum   ; jump if num1 > num2   
    mov  rcx, rdx  ; num2 is greater of the two  
sum: 
    call printf 
mov  rcx, 0 
add  rcx, rsi 

有一个在做这种方式没有任何意义。只需要mov第一个号码变成RCX使用mov rcx, rsi

mov  rdi, dword format_str2 
    mov  rcx, rsi 
    add  rcx, rdx 
    call printf 
相关问题