nasm x64汇编:输入数字比较大小并打印结果

发布于:2024-10-15 ⋅ 阅读:(101) ⋅ 点赞:(0)

Linux下x64汇编。

比较两个数大小:

 extern printf

 section .data
     num1 dd 42
     num2 dd 41
     fmt db "num1=%d %s num2=%d", 10, 0 	; 10'\n',0是'\0'
     OP_G db ">", 0
     OP_LE db "<", 0
 section .bss
 section .text
     global main
 main:
     push rbp
     mov rbp, rsp
     
     xor rax, rax
     xor rbx, rbx
     mov rax, [num1]
     mov rbx, [num2]
     cmp rax, rbx
     jg greater

     mov rdi, fmt	; num1小于OR等于num2
     mov rsi, [num1]
     mov rdx, OP_LE,
     mov rcx, [num2]
     mov rax, 0
     call printf	;相当于printf("num1=%d %s num2=%d", num1, OP_G, num2)
     jmp exit
 greater: 				; num1大于num2
     mov rdi, fmt
     mov rsi, [num1]
     mov rdx, OP_G
     mov rcx, [num2]
     mov rax, 0
     call printf	;相当于printf("num1=%d %s num2=%d", num1, OP_LE, num2)

 exit:
     mov rsp, rbp
     pop rbp
     ret

输出结果:

刚开始写时犯了两个错:

  1. num1定义为num1 dq 42,但是%d需要的是int32,需要用dd类型才对。
  2. 传参时使用mov rsi, num1,这样实际取的是地址,应该用mov rsi, [num1]才是参数值。
  3. mov rax, num1时,寄存器只有低32位被赋值了,高32位里是垃圾值。所以需要用eax或将rax清零。

nasm + gcc编译运行:

$ nasm demo.asm -felf64
$ gcc demo.o -no-pie
% ./a.out
num1=42 > num2=41

使用scanf输入数字

section .data
        num1 dd 42
        num2 dd 41

        info db "input num1 and num2, split with space:", 0
        input_num_fmt db "%d %d", 0

        output_fmt db "num1=%d %s num2=%d", 10, 0
        OP_G db ">", 0
        OP_LE db "<=", 0
section .bss
section .text
        global main
main:
        push rbp
        mov rbp, rsp
;;;;;;;;;;;;;;;;;;;打印提示
        mov rdi, info
        call puts
;;;;;;;;;;;;;;;;;;;等待输入两个数字
        mov rdi, input_num_fmt
        mov rsi, num1
        mov rdx, num2
        call scanf
;;;;;;;;;;;;;;;;;;;比较并打印结果

        mov eax, [num1]
        mov ebx, [num2]
        cmp rax, rbx
        jg greater

        mov rdi, output_fmt
        mov rsi, [num1]
        mov rdx, OP_LE,
        mov rcx, [num2]
        call printf
        jmp exit
greater:
        mov rdi, output_fmt
        mov rsi, [num1]
        mov rdx, OP_G
        mov rcx, [num2]
        call printf
                                                                                                                                       exit:
        mov rsp, rbp
        pop rbp
        ret

输出:

popter@yangqing2:~/asm$ a.out
input num1 and num2, split with space:
1 2
num1=1 <= num2=2
popter@yangqing2:~/asm$ a.out
input num1 and num2, split with space:
1 1
num1=1 <= num2=1
popter@yangqing2:~/asm$ a.out
input num1 and num2, split with space:
1 0
num1=1 > num2=0

参考示例

参考了书上示例:

 ; jump.asm                                    
                                              
 extern printf                                 
 section .data                                 
     number1 dq 42                             
     number2 dq 41                             
     fmt1 db "Number1 >= Number2", 10, 0       
     fmt2 db "Number1 < Number2", 10, 0        
 section .bss                                  
 section .text                                 
     global main                               
 main:                                         
     push rbp                                  
     mov rbp, rsp                              
     mov rax, [number1]                        
     mov rbx, [number2]                        
     cmp rax, rbx                              
     jge greater ;>= 则跳转                    
 mov rdi, fmt2                                 
 mov rax, 0                                    
     call printf                               
     jmp exit                                  
 greater:                                      
     mov rdi, fmt1                             
     mov rax, 0                                
     call printf                               
 exit:                                         
     mov rsp, rbp                              
     pop rbp                                   
     ret                                       

网站公告

今日签到

点亮在社区的每一天
去签到