ARM64函数调用流程分析

ARM64函数调用流程分析

  • 1 ARM64 函数调用实例
  • 2 对应代码的分析
    • 2.1 main函数及其对应的汇编程序
      • 2.1.1 main的C代码实现
      • 2.1.2 main函数对应汇编及其分析
      • 2.1.3 执行完成之后栈的存放情况
    • 2.2 test_fun_a函数及其对应的汇编程序
      • 2.2.1 test_fun_a函数的C实现
      • 2.2.2 test_fun_a函数对应汇编及其分析
      • 2.2.3 执行完成之后栈帧的使用情况
    • 2.3 test_fun_b函数及其对应的汇编程序
      • 2.3.1 test_func_b函数的C实现
      • 2.3.2 test_fun_b函数对应汇编及其分析
      • 2.3.3 执行完成之后栈帧的使用情况

ARM64 程序调用标准

1 ARM64 函数调用实例

下图是介绍一个简单函数调用的示例,在该示例中简单介绍了栈的使用。
在这里插入图片描述

2 对应代码的分析

2.1 main函数及其对应的汇编程序

2.1.1 main的C代码实现

int main(void)
{long a = 1;                                                                             long b = 2;printf("The current function is %s a:%ld b:%ld\r\n", __func__, a, b); test_fun_a(a, b, 0, 1); a = a + b;b = a + b;return 0;
}

2.1.2 main函数对应汇编及其分析

  • 0000000000000114 <main>:main函数的入口
  • 114: a9be7bfd stp x29, x30, [sp, #-32]! 将sp = sp - 32,为main函数开一个32Byte的栈空间,然后将x29(FP),X30(LR)寄存器的值存放在SP和SP + 8的位置处。
  • 118: 910003fd mov x29, sp 将SP寄存器的值存放到X29(FP)寄存器中,即FP寄存器指向当前main函数的栈顶。
  • 11c: d2800020 mov x0, #0x1 // #1 将局部变量a的值保存到x0寄存器中
  • 120: f9000be0 str x0, [sp, #16] 将局部变量a的值保存到sp + 16的位置处。
  • 124: d2800040 mov x0, #0x2 // #2 将局部变量b的值保存到x0寄存器中
  • 128: f9000fe0 str x0, [sp, #24] 将局部变量b的值保存到sp + 24栈内存处
  • 12c: f9400fe3 ldr x3, [sp, #24] 从栈中加载局部变量b的值到x3寄存器中
  • 130: f9400be2 ldr x2, [sp, #16]从栈中加载局部变量a的值到x2寄存器中
  • 134: 90000000 adrp x0, 0 <test_fun_b>加载test_func_b函数的地址到x0寄存器中
  • 138: 91000001 add x1, x0, #0x0将x0 + 0的值保存到x1寄存器中
  • 13c: 90000000 adrp x0, 0 <test_fun_b>加载test_func_b函数的地址到x0寄存器中
  • 140: 91000000 add x0, x0, #0x0将x0 + 0的值保存到x0寄存器中
  • 144: 94000000 bl 0 <printf>调用函数printf
  • 148: d2800023 mov x3, #0x1 // #1将1保存到x3寄存器中,作为调用test_fun_a函数的第4个参数
  • 14c: d2800002 mov x2, #0x0 // #0将0保存到寄存器x2中,作为调用test_fun_a函数的第3个参数
  • 150: f9400fe1 ldr x1, [sp, #24]从栈中取出局部变量b的值,放到x1寄存器中,作为调用test_fun_a的第2个参数
  • 154: f9400be0 ldr x0, [sp, #16]从栈中取出局部变量a的值,放到x0寄存器中,作为调用test_fun_a的第1个参数
  • 158: 94000000 bl 80 <test_fun_a>调用test_func_a函数,其参数分别为前面的x0 ~ x3寄存器的值
  • 15c: f9400be1 ldr x1, [sp, #16] 加载局部变量a的值到x1寄存器
  • 160: f9400fe0 ldr x0, [sp, #24]加载局部变量b的值到x0寄存器
  • 164: 8b000020 add x0, x1, x0 a = a + b
  • 168: f9000be0 str x0, [sp, #16] 将计算到的局部变量a的值重新存到栈中
  • 16c: f9400fe1 ldr x1, [sp, #24]从栈中取出局部变量b的值
  • 170: f9400be0 ldr x0, [sp, #16]从栈中取出局部变量a的值
  • 174: 8b000020 add x0, x1, x0 b = a + b
  • 178: f9000fe0 str x0, [sp, #24]将新计算得到的局部变量b的值重新保存到栈中
  • 17c: 52800000 mov w0, #0x0 // #0给w0寄存器赋值为0,该操作是用在ret指令执行时,返回0值。
  • 180: a8c27bfd ldp x29, x30, [sp], #32恢复x29(FP)和X30(LR)的值,同时SP = SP + 32
  • 184: d65f03c0 ret 返回调用的指令,该指令执行的时候会返回lr寄存器指向的函数中。
                                                                                             
0000000000000114 <main>:114:   a9be7bfd        stp     x29, x30, [sp, #-32]!118:   910003fd        mov     x29, sp11c:   d2800020        mov     x0, #0x1                        // #1120:   f9000be0        str     x0, [sp, #16]124:   d2800040        mov     x0, #0x2                        // #2128:   f9000fe0        str     x0, [sp, #24]12c:   f9400fe3        ldr     x3, [sp, #24]130:   f9400be2        ldr     x2, [sp, #16]134:   90000000        adrp    x0, 0 <test_fun_b>138:   91000001        add     x1, x0, #0x013c:   90000000        adrp    x0, 0 <test_fun_b>140:   91000000        add     x0, x0, #0x0144:   94000000        bl      0 <printf>148:   d2800023        mov     x3, #0x1                        // #114c:   d2800002        mov     x2, #0x0                        // #0150:   f9400fe1        ldr     x1, [sp, #24]154:   f9400be0        ldr     x0, [sp, #16]158:   94000000        bl      80 <test_fun_a>15c:   f9400be1        ldr     x1, [sp, #16]160:   f9400fe0        ldr     x0, [sp, #24]164:   8b000020        add     x0, x1, x0168:   f9000be0        str     x0, [sp, #16]16c:   f9400fe1        ldr     x1, [sp, #24]170:   f9400be0        ldr     x0, [sp, #16]174:   8b000020        add     x0, x1, x0178:   f9000fe0        str     x0, [sp, #24]17c:   52800000        mov     w0, #0x0                        // #0180:   a8c27bfd        ldp     x29, x30, [sp], #32184:   d65f03c0        ret

2.1.3 执行完成之后栈的存放情况

在这里插入图片描述

2.2 test_fun_a函数及其对应的汇编程序

2.2.1 test_fun_a函数的C实现

void test_fun_a(long m, long n, long x, long y)
{long b = 2;long c = 3;printf("The current function is %s b:%ld c:%ld\r\n", __func__, b, c); test_fun_b(b, c, 0, 2); b = b + c + m;c = b + c + n;
}

2.2.2 test_fun_a函数对应汇编及其分析

  • 0000000000000080 <test_fun_a>:test_fun_a函数的入口
  • 80: a9bc7bfd stp x29, x30, [sp, #-64]!为test_fun_a函数开栈64B,同时把X29(FP),X30(LR)保存到栈顶sp和sp + 8的栈内存位置处
  • 84: 910003fd mov x29, sp将sp保存到x29(FP)寄存器中,相当于FP指向栈的栈顶
  • 88: f90017e0 str x0, [sp, #40]将参数1保存到栈的sp + 40栈内存位置处
  • 8c: f90013e1 str x1, [sp, #32]将参数2保存到栈sp + 32的栈内存位置处
  • 90: f9000fe2 str x2, [sp, #24]将参数3保存到栈sp + 24栈内存位置处
  • 94: f9000be3 str x3, [sp, #16]将参数4保存到栈sp + 16栈内存位置处
  • 98: d2800040 mov x0, #0x2 // #2将test_fun_a函数的局部变量b保存到x0寄存器中
  • 9c: f9001be0 str x0, [sp, #48]将test_fun_a函数的局部变量b保存到sp + 48栈内存位置处
  • a0: d2800060 mov x0, #0x3 // #3将test_fun_a函数的局部变量c保存到x1寄存器中
  • a4: f9001fe0 str x0, [sp, #56]将test_fun_a函数的局部变量c保存到栈sp + 56栈内存位置处
  • a8: f9401fe3 ldr x3, [sp, #56]从栈中取出局部变量c的值放到x3寄存器中
  • ac: f9401be2 ldr x2, [sp, #48]从栈中取出局部变量b的值放到x2寄存器中
  • b0: 90000000 adrp x0, 0 <test_fun_b>将test_fun_b函数的地址加载到x0寄存器中
  • b4: 91000001 add x1, x0, #0x0 x1 = x0 + 0,其中x0保存的是test_fun_b的起始地址
  • b8: 90000000 adrp x0, 0 <test_fun_b>将test_fun_b函数的地址加载到x0寄存器中
  • bc: 91000000 add x0, x0, #0x0 x0 = x0 + 0,其中x0保存的是test_fun_b的起始地址
  • c0: 94000000 bl 0 <printf>调用函数printf
  • c4: d2800043 mov x3, #0x2 // #2给x3寄存器赋值为2,作为test_fun_b的第4个参数
  • c8: d2800002 mov x2, #0x0 // #0给x2寄存器赋值为0,作为test_func_b的第三个参数
  • cc: f9401fe1 ldr x1, [sp, #56]从栈中取出局部变量c,存放到x1寄存器,作为test_fun_b的第二个参数
  • d0: f9401be0 ldr x0, [sp, #48]从栈中取出局部变量b,存放到x0寄存器,作为test_fun_b的第一个参数
  • d4: 94000000 bl 0 <test_fun_b>调用test_fun_b函数,x0 ~ x3作为test_fun_a的四个参数
  • d8: f9401be1 ldr x1, [sp, #48]从栈中取出test_fun_a的局部变量b,放到x1寄存器中
  • dc: f9401fe0 ldr x0, [sp, #56]从栈中取出test_fun_a的局部变量c,放到x0寄存器中
  • e0: 8b000020 add x0, x1, x0 c = b + c,将c的结果保存到x0寄存器中。
  • e4: f94017e1 ldr x1, [sp, #40]从栈中取出调用test_fun_a时传入的第1个参数取出,放到x1寄存器中
  • e8: 8b000020 add x0, x1, x0 c = c + m,将计算的结果放到x0寄存器中
  • ec: f9001be0 str x0, [sp, #48]将计算的结果x0的值重新保存到局部变量b的栈内存位置处
  • f0: f9401be1 ldr x1, [sp, #48]从栈中取出局部变量b的值放到x1寄存器中。
  • f4: f9401fe0 ldr x0, [sp, #56]从栈中取出局部变量x的值放到x0寄存器中
  • f8: 8b000020 add x0, x1, x0c = b + c
  • fc: f94013e1 ldr x1, [sp, #32]从栈中取出调用test_fun_a函数时传入的第2个参数放到x1寄存器中
  • 100: 8b000020 add x0, x1, x0 c = c + n,计算的结果放到x0寄存器中
  • 104: f9001fe0 str x0, [sp, #56]将计算的新值存放到原局部变量c的栈内存位置处
  • 108: d503201f nop空操作
  • 10c: a8c47bfd ldp x29, x30, [sp], #64恢复X29(FP),X30(LR)寄存器的值,同时sp = sp + 64栈指针寄存器
  • 110: d65f03c0 ret返回X30(LR)寄存器保存的返回函数处
0000000000000080 <test_fun_a>:80:   a9bc7bfd        stp     x29, x30, [sp, #-64]!84:   910003fd        mov     x29, sp 88:   f90017e0        str     x0, [sp, #40]8c:   f90013e1        str     x1, [sp, #32]90:   f9000fe2        str     x2, [sp, #24]94:   f9000be3        str     x3, [sp, #16]98:   d2800040        mov     x0, #0x2                        // #2   9c:   f9001be0        str     x0, [sp, #48]a0:   d2800060        mov     x0, #0x3                        // #3   a4:   f9001fe0        str     x0, [sp, #56]a8:   f9401fe3        ldr     x3, [sp, #56]ac:   f9401be2        ldr     x2, [sp, #48]b0:   90000000        adrp    x0, 0 <test_fun_b>b4:   91000001        add     x1, x0, #0x0b8:   90000000        adrp    x0, 0 <test_fun_b>bc:   91000000        add     x0, x0, #0x0c0:   94000000        bl      0 <printf>c4:   d2800043        mov     x3, #0x2                        // #2c8:   d2800002        mov     x2, #0x0                        // #0cc:   f9401fe1        ldr     x1, [sp, #56]d0:   f9401be0        ldr     x0, [sp, #48]                                                 d4:   94000000        bl      0 <test_fun_b>d8:   f9401be1        ldr     x1, [sp, #48]dc:   f9401fe0        ldr     x0, [sp, #56]e0:   8b000020        add     x0, x1, x0e4:   f94017e1        ldr     x1, [sp, #40]e8:   8b000020        add     x0, x1, x0ec:   f9001be0        str     x0, [sp, #48]f0:   f9401be1        ldr     x1, [sp, #48]f4:   f9401fe0        ldr     x0, [sp, #56]f8:   8b000020        add     x0, x1, x0fc:   f94013e1        ldr     x1, [sp, #32]100:   8b000020        add     x0, x1, x0104:   f9001fe0        str     x0, [sp, #56]108:   d503201f        nop10c:   a8c47bfd        ldp     x29, x30, [sp], #64110:   d65f03c0        ret

2.2.3 执行完成之后栈帧的使用情况

在这里插入图片描述

2.3 test_fun_b函数及其对应的汇编程序

2.3.1 test_func_b函数的C实现

void test_fun_b(long m, long n, long x, long y)
{long c = 3;long d = 4;printf("The current function is %s c:%ld d:%ld\r\n", __func__, c, d); c = c + d + m;d = c + d + n;
}

2.3.2 test_fun_b函数对应汇编及其分析

  • 0000000000000000 <test_fun_b>:test_fun_b函数的入口
  • 0: a9bc7bfd stp x29, x30, [sp, #-64]!为test_fun_b函数开栈64B,同时把X29(FP),X30(LR)保存到栈顶sp和sp + 8的栈内存位置处
  • 4: 910003fd mov x29, sp将sp保存到x29(FP)寄存器中,相当于FP指向栈的栈顶
  • 8: f90017e0 str x0, [sp, #40]将参数1保存到栈的sp + 40栈内存位置处
  • c: f90013e1 str x1, [sp, #32]将参数2保存到栈sp + 32的栈内存位置处
  • 10: f9000fe2 str x2, [sp, #24]将参数3保存到栈sp + 24栈内存位置处
  • 14: f9000be3 str x3, [sp, #16]将参数4保存到栈sp + 16栈内存位置处
  • 18: d2800060 mov x0, #0x3 // #3将test_fun_b函数的局部变量c保存到x0寄存器中
  • 1c: f9001be0 str x0, [sp, #48]将test_fun_b函数的局部变量c保存到sp + 48栈内存位置处
  • 20: d2800080 mov x0, #0x4 // #4将test_fun_b函数的局部变量d保存到x1寄存器中
  • 24: f9001fe0 str x0, [sp, #56]将test_fun_b函数的局部变量d保存到栈sp + 56栈内存位置处
  • 28: f9401fe3 ldr x3, [sp, #56]从栈中取出局部变量d的值放到x3寄存器中
  • 2c: f9401be2 ldr x2, [sp, #48]从栈中取出局部变量c的值放到x2寄存器中
  • 30: 90000000 adrp x0, 0 <test_fun_b>将test_fun_b函数的地址加载到x0寄存器中
  • 34: 91000001 add x1, x0, #0x0x1 = x0 + 0,其中x0保存的是test_fun_b的起始地址
  • 38: 90000000 adrp x0, 0 <test_fun_b>将test_fun_b函数的地址加载到x0寄存器中
  • 3c: 91000000 add x0, x0, #0x0x0 = x0 + 0,其中x0保存的是test_fun_b的起始地址
  • 40: 94000000 bl 0 <printf>调用函数printf
  • 44: f9401be1 ldr x1, [sp, #48]从栈中取出局部变量c,存放到x1寄存器
  • 48: f9401fe0 ldr x0, [sp, #56]从栈中取出局部变量d,存放到x0寄存器
  • 4c: 8b000020 add x0, x1, x0 d = c + d,将d的结果保存到x0寄存器中。
  • 50: f94017e1 ldr x1, [sp, #40]从栈中取出调用test_fun_b时传入的第1个参数取出,放到x1寄存器中
  • 54: 8b000020 add x0, x1, x0 d = d + m
  • 58: f9001be0 str x0, [sp, #48]将计算的结果x0的值重新保存到局部变量c的栈内存位置处
  • 5c: f9401be1 ldr x1, [sp, #48]从栈中取出局部变量c的值放到x1寄存器中。
  • 60: f9401fe0 ldr x0, [sp, #56]从栈中取出局部变量d的值放到x0寄存器中
  • 64: 8b000020 add x0, x1, x0 c = c + d
  • 68: f94013e1 ldr x1, [sp, #32]从栈中取出调用test_fun_b函数时传入的第2个参数放到x1寄存器中
  • 6c: 8b000020 add x0, x1, x0 c = c + n
  • 70: f9001fe0 str x0, [sp, #56]将计算的新值存放到原局部变量d的栈内存位置处
  • 74: d503201f nop空操作
  • 78: a8c47bfd ldp x29, x30, [sp], #64恢复X29(FP),X30(LR)寄存器的值,同时sp = sp + 64栈指针寄存器
  • 7c: d65f03c0 ret返回X30(LR)寄存器保存的返回函数处
0000000000000000 <test_fun_b>:0:   a9bc7bfd        stp     x29, x30, [sp, #-64]!4:   910003fd        mov     x29, sp8:   f90017e0        str     x0, [sp, #40]c:   f90013e1        str     x1, [sp, #32]10:   f9000fe2        str     x2, [sp, #24]14:   f9000be3        str     x3, [sp, #16]18:   d2800060        mov     x0, #0x3                        // #31c:   f9001be0        str     x0, [sp, #48]20:   d2800080        mov     x0, #0x4                        // #424:   f9001fe0        str     x0, [sp, #56]28:   f9401fe3        ldr     x3, [sp, #56]2c:   f9401be2        ldr     x2, [sp, #48]30:   90000000        adrp    x0, 0 <test_fun_b>                                            34:   91000001        add     x1, x0, #0x038:   90000000        adrp    x0, 0 <test_fun_b>3c:   91000000        add     x0, x0, #0x040:   94000000        bl      0 <printf>44:   f9401be1        ldr     x1, [sp, #48]48:   f9401fe0        ldr     x0, [sp, #56]4c:   8b000020        add     x0, x1, x050:   f94017e1        ldr     x1, [sp, #40]54:   8b000020        add     x0, x1, x058:   f9001be0        str     x0, [sp, #48]5c:   f9401be1        ldr     x1, [sp, #48]60:   f9401fe0        ldr     x0, [sp, #56]64:   8b000020        add     x0, x1, x068:   f94013e1        ldr     x1, [sp, #32]6c:   8b000020        add     x0, x1, x070:   f9001fe0        str     x0, [sp, #56]74:   d503201f        nop     78:   a8c47bfd        ldp     x29, x30, [sp], #647c:   d65f03c0        ret

2.3.3 执行完成之后栈帧的使用情况

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/51448.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Oracle的学习心得和知识总结(二十八)|Oracle数据库数据库回放功能之论文二翻译及学习

目录结构 注&#xff1a;提前言明 本文借鉴了以下博主、书籍或网站的内容&#xff0c;其列表如下&#xff1a; 1、参考书籍&#xff1a;《Oracle Database SQL Language Reference》 2、参考书籍&#xff1a;《PostgreSQL中文手册》 3、EDB Postgres Advanced Server User Gui…

MAC电脑外放没有声音解决方案

烦人呐&#xff0c;我的mac外接显示屏幕&#xff0c;显示器没有音频输出&#xff0c;需要mac笔记本的音频输出&#xff0c;但是经常打开后&#xff0c;mac没有声音输出&#xff0c;需要重启电脑才能生效。亲测一下方法有效&#xff0c;请参考&#xff1a; 文章目录 一、短期方案…

基于mha+mycat2+gtid的半同步主从复制双vip高可用MySQL集群

目录 项目名称 项目架构图 项目概述 项目准备 项目步骤 一、使用ansible编写palybook实现4台二进制安装MySQL环境的部署&#xff0c;并把master上的基础数据下发到所有slave服务器上 1. 建立免密通道 2.安装ansible在ansible服务器上&#xff0c;并写好主机清单 3.将…

汽车电子笔记之:AUTOSA架构下的OS概述

目录 1、实时操作系统&#xff08;RTOS&#xff09; 2、OSEK操作系统 2.1、OSEK概述 2.2、OSEK处理等级 2.3、OSEK任务符合类 2.4、OSEK优先级天花板模式 3、AUTOSAR OS 3.1、 AUTOSAR OS对OSEK OS的继承和扩展 3.2、AUTOSAR OS的调度表 3.3、AUTOSAR OS的时间保护 3…

冷冻冷藏自动化立体库|HEGERLS四向穿梭车助力打造冷链智能仓储新力量

随着中国仓储物流整体规模和低温产品消费需求的稳步增长&#xff0c;冷链市场应用潜力不断释放。而在实际运行中&#xff0c;由于冷库容量不足、基础设施落后、管理机制欠缺等原因&#xff0c;经常出现“断链”现象&#xff0c;严重威胁到产品质量和消费者安全。 河北沃克金属…

尚硅谷大数据项目《在线教育之离线数仓》笔记004

视频地址&#xff1a;尚硅谷大数据项目《在线教育之离线数仓》_哔哩哔哩_bilibili 目录 第9章 数仓开发之DWD层 P049 P050 P051 P052 P053 P054 P055 P056 P057 P058 P059 P060 P061 P062 P063 P064 P065 P066 P067 P068 P069 P070 第9章 数仓开发之DWD…

Wlan——锐捷零漫游网络解决方案以及相关配置

目录 零漫游介绍 一代零漫游 二代单频率零漫游 二代双频率零漫游 锐捷零漫游方案总结 锐捷零漫游方案的配置 配置无线信号的信道 开启关闭5G零漫游 查看配置 零漫游介绍 普通的漫游和零漫游的区别 普通漫游 漫游是由一个AP到另一个AP或者一个射频卡到另一个射频卡的漫…

深入理解 Vue Router:构建可靠的前端路由系统

目录 01-什么是前端路由以及路由两种模式实现原理02-路由的基本搭建与嵌套路由模式03-动态路由模式与编程式路由模式04-命名路由与命名视图与路由元信息05-路由传递参数的多种方式及应用场景06-详解route对象与router对象07-路由守卫详解及应用场景 01-什么是前端路由以及路由两…

java:Servlet

背景 我们访问浏览器访问一个地址&#xff0c;最终是访问到了这个 java 类&#xff0c;而 java 是运行在 Tomcat 上的&#xff0c;所以 Tomcat 作为一个服务器会把这个访问地址指向这个类中&#xff0c;这个类就是 Servlet&#xff0c;Servlet 就是一个具有一定规范的类&#x…

whisper 语音识别项目部署

1.安装anaconda软件 在如下网盘免费获取软件&#xff1a; 链接&#xff1a;https://pan.baidu.com/s/1zOZCQOeiDhx6ebHh5zNasA 提取码&#xff1a;hfnd 2.使用conda命令创建python3.8环境 conda create -n whisper python3.83.进入whisper虚拟环境 conda activate whisper4.…

英特尔开始加码封装领域 | 百能云芯

在积极推进先进制程研发的同时&#xff0c;英特尔正在加大先进封装领域的投入。在这个背景下&#xff0c;该公司正在马来西亚槟城兴建一座全新的封装厂&#xff0c;以加强其在2.5D/3D封装布局领域的实力。据了解&#xff0c;英特尔计划到2025年前&#xff0c;将其最先进的3D Fo…

Facebook HiPlot “让理解高维数据变得容易”

在这个全球信息化的时代&#xff0c;数据量呈爆炸式增长&#xff0c;数据的复杂性也是如此。如何有效地处理高维数据并找到隐藏在其中的相关性和模式是一个严峻的挑战。近年来&#xff0c;可视化和可视化分析已被应用于该任务&#xff0c;并取得了一些积极成果。Facebook的新Hi…

Kali Linux 2023.3 发布

Offective Security 发布了 Kali Linux 2023.3&#xff0c;这是其渗透测试和数字取证平台的最新版本。 Kali Linux 2023.3 中的新工具 除了对当前工具的更新之外&#xff0c;新版本的 Kali 通常还会引入新的工具。 这次&#xff0c;他们是&#xff1a; Calico – 云原生网络…

ubuntu20.04 直接安装vpp23.06 测试双 VPP Tunnel Ike2

环境信息&#xff1a;VMware Workstation 17 Pro ubuntu20.04 (清华源) ubuntu 源点进去选&#xff1a;ubuntu-22.04.3-desktop-amd64.iso 如果之前装过VPP&#xff0c;用以下命令确定是否卸载干净&#xff1a; dpkg -l | grep vpp dpkg -l | grep DPDK 卸载&#xff1a; …

【数据仓库】Linux、CentOS源码安装Superset

Linux、CentOS源码安装Superset步骤&#xff0c;遇到的各种问题。 报错问题&#xff1a; Linux下pip版本问题 You are using pip version 8.1.2, however version 22.2.2 is available. 解决办法&#xff1a; 安装python3的pip yum install python3-pip再升级 pip3 install…

stm32 之20.HC-06蓝牙模块

原理图显示使用usart3串口使用的是PB10和PB11引脚 直接配置usart3串口协议 void usart3_init(uint32_t baud) {GPIO_InitTypeDef GPIO_InitStructureure;USART_InitTypeDef USART_InitStructure;NVIC_InitTypeDef NVIC_InitStructure;//端口B硬件时钟打开RCC_AHB1PeriphClockC…

如何通过tomcat下载映射下载文件

1.1找到tomcat服务器中server.xml文件 !--doBase是静态资源路径位置&#xff0c; path作用相当于设置的key, doBase作用相当于value --> <Context path"/download" docBase"E:\testBackData"></Context>1.2 找到tomcat服务器中web.xml文…

LAMP架构介绍配置命令讲解

LAMP架构介绍配置命令讲解 一、LAMP架构介绍1.1概述1.2LAMP各组件的主要作用1.3各组件的安装顺序 二、编译安装Apache httpd服务---命令讲解1、关闭防火墙&#xff0c;将安装Apache所需的软件包传到/opt/目录下2、安装环境依赖包3、配置软件模块4、编译安装5、优化配置文件路径…

鼠标拖拽盒子移动

目录 需求思路代码页面展示【补充】纯js实现 需求 浮动的盒子添加鼠标拖拽功能 思路 给需要拖动的盒子添加鼠标按下事件鼠标按下后获取鼠标点击位置与盒子边缘的距离给 document 添加鼠标移动事件鼠标移动过程中&#xff0c;将盒子的位置进行重新定位侦听 document 鼠标弹起&a…

Grounded Language-Image Pre-training论文笔记

Title&#xff1a;Grounded Language-Image Pre-training Code 文章目录 1. 背景2. 方法&#xff08;1&#xff09;Unified Formulation传统目标检测grounding目标检测 &#xff08;2&#xff09;Language-Aware Deep Fusion&#xff08;3&#xff09;Pre-training with Scala…