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
输出结果:
刚开始写时犯了两个错:
num1
定义为num1 dq 42
,但是%d
需要的是int32
,需要用dd
类型才对。- 传参时使用
mov rsi, num1
,这样实际取的是地址,应该用mov rsi, [num1]
才是参数值。 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