这个汇编版的求最大数的函数还是有很多亮点的:
如何计算.data里面某个数组的总字节数。
如何使用除法指令,被除数要放到%eax里面,除数要放到%ebx里面
如何使用leaq把地址复制到某个寄存器中
cmovl指令,带条件的赋值语句
code:
.section .data
data_item:
.long 1,2,3,4,5,6,7,8,9,10,15, -1, 99
data_item_end:
.equ data_item_len, data_item_end - data_item
fmt:
.ascii "%d\n\0"
.section .text
.global _start
_start:
movq $data_item_len, %rax #rax里面是被除数
movl %eax, %edx
movl $4, %ebx #除数
sarl $31, %edx
divl %ebx
pushq %rax #数组长度
pushq $data_item #数组元素首地址
call max_num
addq $16, %rsp
movl %eax, %esi
movl $fmt, %edi
xorl %eax, %eax
call printf
xorl %edi, %edi
call exit
.type max_num, @function
max_num:
pushq %rbp
movq %rsp, %rbp
movq 16(%rbp), %rdi #第一个参数
movl 24(%rbp), %esi #第二个参数
movl -4(%rdi, %rsi, 4), %eax
leaq -4(%rdi, %rsi, 4), %rdx
jmp max_num_end
max_num_loop_start:
movl (%rdx), %ecx
subl $1, %esi
cmpl %ecx, %eax
cmovl %ecx, %eax
subq $4, %rdx
max_num_end:
testl %esi, %esi
jg max_num_loop_start
movq %rbp, %rsp
popq %rbp
ret
编译脚本:
gcc -c max_num.s -g && ld ./max_num.o -lc -dynamic-linker /lib64/ld-linux-x86-64.so.2 && ./a.out
如同如下的c code:
#include <stdio.h>
int max_num(int *arr, int n) {
int max;
int i;
max = arr[n - 1];
while (n-- > 0) {
if (max < arr[n])
max = arr[n];
}
return max;
}
int main() {
int arr[] = {1, 2, 3, 4, 5, 6};
printf("%d\n", max_num(arr, 6));
return 0;
}