【Linux内核】ATT汇编编程练习
编写AT&T汇编程序,接收正整数输入n,计算1到n的和,并打印在屏幕上。
LInux下,先安装GCC,编写r如下代码,命名为sum.s
.section .data
input_buffer: .space 32 # 输入缓冲区
output_buffer: .space 32 # 输出缓冲区
.section .text
.globl _start
_start:
# 读取输入
mov $0, %rax # sys_read
mov $0, %rdi # stdin
lea input_buffer(%rip), %rsi
mov $32, %rdx
syscall
# 将ASCII字符串转为整数n
xor %rbx, %rbx # 清空rbx存储n
lea input_buffer(%rip), %rsi
mov %rax, %rcx # 实际读取字节数
convert_input:
movb (%rsi), %al
cmp $10, %al # 检测换行符
je calculate_sum
sub $48, %al # ASCII转数字
imul $10, %rbx
add %rax, %rbx
inc %rsi
loop convert_input
calculate_sum:
# 计算sum = n*(n+1)/2
mov %rbx, %rax
inc %rax
mul %rbx
shr $1, %rax # 结果在rax中
# 将整数转为ASCII字符串
lea output_buffer(%rip), %rdi
mov %rax, %r8 # 保存计算结果
mov $10, %r9 # 除数
xor %rcx, %rcx # 字符计数器
push_digits:
xor %rdx, %rdx
div %r9 # rax=商, rdx=余数
add $48, %dl # 数字转ASCII
push %rdx # 压栈保存字符
inc %rcx
test %rax, %rax
jnz push_digits
# 从栈中弹出字符到输出缓冲区
mov %rcx, %rdx # 保存字符数量
pop_digits:
pop %rax
mov %al, (%rdi)
inc %rdi
loop pop_digits
# 添加换行符
movb $10, (%rdi)
inc %rdx
# 输出结果
mov $1, %rax # sys_write
mov $1, %rdi # stdout
lea output_buffer(%rip), %rsi
syscall
# 退出程序
mov $60, %rax # sys_exit
xor %rdi, %rdi
syscall
编译生成目标文件sum.o:
[joseph@localhost asm]$ as sum.s -o sum.o
链接,生成sum可执行文件:
[joseph@localhost asm]$ ld sum.o -o sum
运行:
[joseph@localhost asm]$ ./sum
100
5050
[joseph@localhost asm]$