在C代码里面,函数的变量除了常规变量,也有指针类型变量。这里,我介绍一下汇编里面对参数是指针类型和整型的处理
直接上代码,代码里有详细的注释:
汇编函数代码:
.data
format: .asciz "%llx %llx %llx\n"
format_int: .asciz "%d %d\n"
.text
.global print_int
print_int:
sub sp, sp, 64 // sp = sp - 16 , 申请16 bytes的栈空间
stp x29, x30, [sp, 0] // 将 FP(x29), LR(x30) 保存在栈底
//add x29, sp, 0 // 新的栈底
mov x29, sp
mov x2, x1
mov x1, x0
ldr x0, =format_int
bl printf
mov w0, 0 // 返回值
ldp x29, x30, [sp, 0] // 将旧的栈底和返回代码恢复
add sp, sp, 64 // 将栈顶恢复
ret
.global print_arry
print_arry:
sub sp, sp, 64 // sp = sp - 16 , 申请16 bytes的栈空间
stp x29, x30, [sp, 0] // 将 FP(x29), LR(x30) 保存在栈底
//add x29, sp, 0 // 新的栈底
mov x29, sp
str x0, [sp, 16] //x0保存的是传进来的参数指针,将该指针保存到 sp+16偏移处
ldr x10, [sp, 16] //将sp+16偏移处的值加载到x10寄存器里面
ldr x10, [x10] //将x10寄存器里面的值对应内存的值加载到x10寄存器里面 加载完毕后,x10就是指针指向的第一个元素
str x10, [sp, 24]
ldr x10, [sp, 16]
ldr x10, [x10, 8]
str x10, [sp, 32]
ldr x10, [sp, 16]
ldr x10, [x10, 16]
str x10, [sp, 40]
ldr x0, =format
ldr x1, [sp, 24]
ldr x2, [sp, 32]
ldr x3, [sp, 40]
bl printf
mov w0, 0 // 返回值
ldp x29, x30, [sp, 0] // 将旧的栈底和返回代码恢复
add sp, sp, 64 // 将栈顶恢复
ret
c代码:
#include <stdio.h>
extern int print_arry(unsigned long int *arry);
extern int print_int(int num1, int num2);
int main(int argc, char *argv[])
{
unsigned long int arry[5] = {0x1111111111111111,0x2222222222222222,0x3333333333333333,0x4444444444444444,0x5555555555555555};
printf("this is main.\n");
print_arry(arry);
print_int(111, 222);
return 0;
}
编译脚本:
#!/bin/sh
ARM_GCC_PATH=/home/CN/qidong.liu/qualcom/820a/apq8096au-lv-4-0_hlos_dev/apps_proc/poky/build/tmp-glibc/sysroots/x86_64-linux/usr/bin/aarch64-agl-linux
ARM_SYSROOT=/home/CN/qidong.liu/qualcom/820a/apq8096au-lv-4-0_hlos_dev/apps_proc/poky/build/tmp-glibc/sysroots/8x96autodvrs
export PATH=$PATH:$ARM_GCC_PATH
aarch64-agl-linux-gcc func.S hello.c -o hello --sysroot=$ARM_SYSROOT
程序执行结果:
root@8x96autodvrs:/data# ./hello
this is main.
1111111111111111 2222222222222222 3333333333333333
111 222
root@8x96autodvrs:/data#
说明:在汇编函数里面,我们只打印了该函数参数对应指针前3个元素
先保存一下,本文还未完成。