X86_64函数调用汇编程序分析
X86_64函数调用汇编程序分析
- 1 X86_64寄存器使用标准
- 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 执行完成之后栈帧的使用情况
- 3 X86_64 函数调用示例及其栈帧示意图
- 4 编译和反汇编的命令
- 4.1 编译的命令
- 4.2 反汇编的命令
1 X86_64寄存器使用标准
- %rdi, %rsi, %rdx, %rcx, %r8, %r9分别用于函数调用过程中的前6个参数,对于6的参数存放在栈中传递
- %rsp用做栈指针寄存器,指向栈顶
- %rbp用作栈框寄存器,指向栈底
- %rax用做函数返回值的第一个寄存器

2 对应代码的分析
2.1 main函数及其对应的汇编程序
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.1 main的C代码实现
2.1.2 main函数对应汇编及其分析
这段汇编代码实现了一个简单的程序,其功能如下:
- 首先,
endbr64指令用于清除处理器的前瞻指令缓存,确保后面的指令正确执行。 push %rbp和mov %rsp,%rbp这两个指令用于保存和设置栈帧的基址指针(Base Pointer)。sub $0x10,%rsp指令用于为局部变量和保存的寄存器值分配栈空间。movq $0x1,-0x10(%rbp)和movq $0x2,-0x8(%rbp)这两个指令用于将字面量1和2存储到栈中的特定位置。mov -0x8(%rbp),%rdx和mov -0x10(%rbp),%rax这两个指令用于从栈中获取之前保存的值。mov %rdx,%rcx和mov %rax,%rdx这两个指令用于将寄存器的值进行传递,为后面的函数调用做准备。lea 0xdf8(%rip),%rsi和lea 0xda6(%rip),%rdi这两个指令用于设置printf函数的参数,分别对应格式字符串和要打印的变量。mov $0x0,%eax指令用于设置系统调用的编号(这里为0,即系统调用号)。callq 1050 <printf@plt>这个指令发起系统调用,执行printf函数,打印输出指定的字符串和数值。- 接下来,
mov -0x8(%rbp),%rsi、mov -0x10(%rbp),%rax、mov $0x1,%ecx、mov $0x0,%edx和mov %rax,%rdi这些指令用于设置函数test_fun_a的参数。 callq 11e8 <test_fun_a>这个指令调用函数test_fun_a,执行其代码。- 在函数
test_fun_a执行完成后,通过一系列的移动和加法操作,将返回值存储回原始的参数位置。 - 最后,
mov $0x0,%eax、leaveq和retq这些指令用于清理栈帧、结束当前函数并返回。
这段汇编代码的功能是调用函数test_fun_a,并打印输出两个数值1和2,然后调用函数test_fun_a并将返回值存储回原始的参数位置。
000000000000128a <main>:128a: f3 0f 1e fa endbr64 128e: 55 push %rbp128f: 48 89 e5 mov %rsp,%rbp1292: 48 83 ec 10 sub $0x10,%rsp1296: 48 c7 45 f0 01 00 00 movq $0x1,-0x10(%rbp)129d: 00 129e: 48 c7 45 f8 02 00 00 movq $0x2,-0x8(%rbp)12a5: 00 12a6: 48 8b 55 f8 mov -0x8(%rbp),%rdx12aa: 48 8b 45 f0 mov -0x10(%rbp),%rax12ae: 48 89 d1 mov %rdx,%rcx12b1: 48 89 c2 mov %rax,%rdx12b4: 48 8d 35 f8 0d 00 00 lea 0xdf8(%rip),%rsi # 20b3 <__func__.2519>12bb: 48 8d 3d a6 0d 00 00 lea 0xda6(%rip),%rdi # 2068 <_IO_stdin_used+0x68>12c2: b8 00 00 00 00 mov $0x0,%eax12c7: e8 84 fd ff ff callq 1050 <printf@plt>12cc: 48 8b 75 f8 mov -0x8(%rbp),%rsi12d0: 48 8b 45 f0 mov -0x10(%rbp),%rax12d4: b9 01 00 00 00 mov $0x1,%ecx12d9: ba 00 00 00 00 mov $0x0,%edx12de: 48 89 c7 mov %rax,%rdi12e1: e8 02 ff ff ff callq 11e8 <test_fun_a>12e6: 48 8b 45 f8 mov -0x8(%rbp),%rax12ea: 48 01 45 f0 add %rax,-0x10(%rbp)12ee: 48 8b 45 f0 mov -0x10(%rbp),%rax12f2: 48 01 45 f8 add %rax,-0x8(%rbp)12f6: b8 00 00 00 00 mov $0x0,%eax12fb: c9 leaveq 12fc: c3 retq 12fd: 0f 1f 00 nopl (%rax)
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 a = x;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, a, 2); b = b + c + m;c = b + c + n;
}
2.2.2 test_fun_a函数对应汇编及其分析
这段汇编代码是一个函数test_fun_a的实现,其功能大致如下:
push %rbp和mov %rsp,%rbp用于保存和设置栈帧的基址指针(Base Pointer)。sub $0x40,%rsp用于为局部变量和保存的寄存器值分配栈空间。mov %rdi,-0x28(%rbp)、mov %rsi,-0x30(%rbp)、mov %rdx,-0x38(%rbp)和mov %rcx,-0x40(%rbp)用于将参数传递到栈帧中的指定位置。mov %rax,-0x18(%rbp)将某个值(可能是函数内的临时变量或计算结果)保存到栈帧的另一个位置。movq $0x2,-0x10(%rbp)和movq $0x3,-0x8(%rbp)用于将字面量值2和3存储到栈中的特定位置。mov -0x8(%rbp),%rdx和mov -0x10(%rbp),%rax用于从栈中获取之前保存的值。lea 0xe77(%rip),%rsi和lea 0xe00(%rip),%rdi用于设置printf函数的参数,分别对应格式字符串和要打印的变量。mov $0x0,%eax用于设置系统调用的编号(这里为0,即系统调用号)。callq 1050 <printf@plt>发起系统调用,执行printf函数,打印输出指定的字符串和数值。mov -0x18(%rbp),%rdx、mov -0x8(%rbp),%rsi、mov -0x10(%rbp),%rax、mov $0x2,%ecx和mov %rax,%rdi用于设置函数test_fun_b的参数。callq 1149 <test_fun_b>调用函数test_fun_b,执行其代码。- 在函数
test_fun_b执行完成后,将返回值存储到栈帧的特定位置。 - 最后,通过一系列的移动和加法操作,将计算结果存储回原始的第一个参数的位置。
48 8b 45 d0 mov -0x30(%rbp),%rax: 将栈帧中偏移为-0x30的位置的值加载到寄存器rax中。48 01 d0 add %rdx,%rax: 将rax和rdx寄存器的值相加,并将结果存储回rax寄存器中。48 89 45 f8 mov %rax,-0x8(%rbp): 将rax寄存器的值存储回栈帧中偏移为-0x8的位置。90: 无操作,用于填充指令。c9:leaveq指令用于撤销栈帧,恢复调用前的堆栈状态。c3:retq指令用于从当前函数返回,返回到调用者的代码位置。
00000000000011e8 <test_fun_a>:11e8: f3 0f 1e fa endbr64 11ec: 55 push %rbp11ed: 48 89 e5 mov %rsp,%rbp11f0: 48 83 ec 40 sub $0x40,%rsp11f4: 48 89 7d d8 mov %rdi,-0x28(%rbp)11f8: 48 89 75 d0 mov %rsi,-0x30(%rbp)11fc: 48 89 55 c8 mov %rdx,-0x38(%rbp)1200: 48 89 4d c0 mov %rcx,-0x40(%rbp)1204: 48 8b 45 c8 mov -0x38(%rbp),%rax1208: 48 89 45 e8 mov %rax,-0x18(%rbp)120c: 48 c7 45 f0 02 00 00 movq $0x2,-0x10(%rbp)1213: 00 1214: 48 c7 45 f8 03 00 00 movq $0x3,-0x8(%rbp)121b: 00 121c: 48 8b 55 f8 mov -0x8(%rbp),%rdx1220: 48 8b 45 f0 mov -0x10(%rbp),%rax1224: 48 89 d1 mov %rdx,%rcx1227: 48 89 c2 mov %rax,%rdx122a: 48 8d 35 77 0e 00 00 lea 0xe77(%rip),%rsi # 20a8 <__func__.2513>1231: 48 8d 3d 00 0e 00 00 lea 0xe00(%rip),%rdi # 2038 <_IO_stdin_used+0x38>1238: b8 00 00 00 00 mov $0x0,%eax123d: e8 0e fe ff ff callq 1050 <printf@plt>1242: 48 8b 55 e8 mov -0x18(%rbp),%rdx1246: 48 8b 75 f8 mov -0x8(%rbp),%rsi124a: 48 8b 45 f0 mov -0x10(%rbp),%rax124e: b9 02 00 00 00 mov $0x2,%ecx1253: 48 89 c7 mov %rax,%rdi1256: e8 ee fe ff ff callq 1149 <test_fun_b>125b: 48 8b 55 f0 mov -0x10(%rbp),%rdx125f: 48 8b 45 f8 mov -0x8(%rbp),%rax1263: 48 01 c2 add %rax,%rdx1266: 48 8b 45 d8 mov -0x28(%rbp),%rax126a: 48 01 d0 add %rdx,%rax126d: 48 89 45 f0 mov %rax,-0x10(%rbp)1271: 48 8b 55 f0 mov -0x10(%rbp),%rdx1275: 48 8b 45 f8 mov -0x8(%rbp),%rax1279: 48 01 c2 add %rax,%rdx127c: 48 8b 45 d0 mov -0x30(%rbp),%rax1280: 48 01 d0 add %rdx,%rax1283: 48 89 45 f8 mov %rax,-0x8(%rbp)1287: 90 nop1288: c9 leaveq 1289: c3 retq
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 a = y;long b = m;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 + a;d = c + d + n + b;
}
2.3.2 test_fun_b函数对应汇编及其分析
这段汇编代码是一个函数test_fun_b的实现。下面是对代码的逐行解释:
1149: f3 0f 1e fa - endbr64指令用于结束64位BR(Branch Prediction)指令的预测。
114d: 55 - push %rbp将当前栈帧的基址指针(Base Pointer,简称RBp)压入栈中,为新的栈帧做准备。
114e: 48 89 e5 - mov %rsp,%rbp将当前栈帧的栈指针(Stack Pointer,简称SP)复制给基址指针(RBp),建立新的栈帧。
1151: 48 83 ec 40 - sub $0x40,%rsp从SP中减去0x40个字节,扩展栈空间。
1155: 48 89 7d d8 - mov %rdi,-0x28(%rbp)将函数参数rdi的值存储到当前栈帧的-0x28位置。
1159: 48 89 75 d0 - mov %rsi,-0x30(%rbp)将函数参数rsi的值存储到当前栈帧的-0x30位置。
115d: 48 89 55 c8 - mov %rdx,-0x38(%rbp)将函数参数rdx的值存储到当前栈帧的-0x38位置。
1161: 48 89 4d c0 - mov %rcx,-0x40(%rbp)将函数参数rcx的值存储到当前栈帧的-0x40位置。
1165: 48 8b 45 c0 - mov -0x40(%rbp),%rax将当前栈帧的-0x40位置的值加载到寄存器rax中。
1169: 48 89 45 e0 - mov %rax,-0x20(%rbp)将寄存器rax的值存储到当前栈帧的-0x20位置。
116d: 48 8b 45 d8 - mov -0x28(%rbp),%rax将当前栈帧的-0x28位置的值加载到寄存器rax中。
1171: 48 89 45 e8 - mov %rax,-0x18(%rbp)将寄存器rax的值存储到当前栈帧的-0x18位置。
1175: 48 c7 45 f0 03 00 00 00 - movq $0x3,-0x10(%rbp)将立即数0x3存储到当前栈帧的-0x10位置。
117d: 48 c7 45 f8 04 00 00 00 - movq $0x4,-0x8(%rbp)将立即数0x4存储到当前栈帧的-0x8位置。
1185: 48 8b 55 f8 - mov -0x8(%rbp),%rdx将当前栈帧的-0x8位置的值加载到寄存器rdx中。
1189: 48 8b 45 f0 - mov -0x10(%rbp),%rax将当前栈帧的-0x10位置的值加载到寄存器rax中。
118d: 48 89 d1 - mov %rdx,%rcx将寄存器rdx的值复制给rcx。
1190: 48 89 c2 - mov %rax,%rdx将寄存器rax的值复制给rdx。
1193: 48 8d 35 fe 0e 00 00 - lea 0xefe(%rip),%rsi将相对地址0xefe处的值加载到寄存器rsi。
119a: 48 8d 3d 67 0e 00 00 - lea 0xe67(%rip),%rdi将相对地址0xe67处的值加载到寄存器rdi。
11a1: b8 00 00 00 00 - mov $0x0,%eax将立即数0x0加载到寄存器eax。
11a6: e8 a5 fe ff ff - callq 1050 <printf@plt>调用函数plt的printf函数,跳转到地址1050处执行。
接下来的指令继续处理计算结果,并执行一些算术操作。
11ab: 48 8b 55 f0 - mov -0x10(%rbp),%rdx将当前栈帧的-0x10位置的值加载到寄存器rdx中。
11af: 48 8b 45 f8 - mov -0x8(%rbp),%rax将当前栈帧的-0x8位置的值加载到寄存器rax中。
11b3: 48 01 c2 - add %rax,%rdx将寄存器rax和rdx的值相加,结果存储在rdx中。
11b6: 48 8b 45 d8 - mov -0x28(%rbp),%rax将当前栈帧的-0x28位置的值加载到寄存器rax中。
11bd: 48 01 c2 - add %rax,%rdx将寄存器rax和rdx的值相加,结果存储在rdx中。
11c1: 48 8b 45 e0 - mov -0x20(%rbp),%rax将当前栈帧的-0x20位置的值加载到寄存器rax中。
11c4: 48 01 d0 - add %rdx,%rax将寄存器rdx和rax的值相加,结果存储在rax中。
11c8: 48 89 45 f0 - mov %rax,-0x10(%rbp)将寄存器rax的值存储到当前栈帧的-0x10位置。
11cc: 48 8b 45 f8 mov -0x8(%rbp),%rax将当前栈帧的-0x8位置的值加载到rax寄存器中
11d0: 48 01 c2 add %rax,%rdx将寄存器rax和rdx的值相加,结果存储在rdx中。
11d3: 48 8b 45 d0 mov -0x30(%rbp),%rax将当前栈帧的-0x30位置的值加载到rax寄存器中
11d7: 48 01 c2 add %rax,%rdx 将寄存器rax和rdx的值相加,结果存储在rdx中。
11da: 48 8b 45 e8 mov -0x18(%rbp),%rax将当前栈帧的-0x18位置的值加载到rax寄存器中
11de: 48 01 d0 add %rdx,%rax 将寄存器rdx和rax的值相加,结果存储在rax中。
11e1: 48 89 45 f8 mov %rax,-0x8(%rbp)将寄存器rax的值存储到当前栈帧的-0x8位置。
11e5: 90 nop
11e6: c9 leaveq 撤销栈帧,恢复调用前的堆栈状态。
11e7: c3 retq从当前函数返回,返回到调用者的代码位置。
0000000000001149 <test_fun_b>:1149: f3 0f 1e fa endbr64 114d: 55 push %rbp114e: 48 89 e5 mov %rsp,%rbp1151: 48 83 ec 40 sub $0x40,%rsp1155: 48 89 7d d8 mov %rdi,-0x28(%rbp)1159: 48 89 75 d0 mov %rsi,-0x30(%rbp)115d: 48 89 55 c8 mov %rdx,-0x38(%rbp)1161: 48 89 4d c0 mov %rcx,-0x40(%rbp)1165: 48 8b 45 c0 mov -0x40(%rbp),%rax1169: 48 89 45 e0 mov %rax,-0x20(%rbp)116d: 48 8b 45 d8 mov -0x28(%rbp),%rax1171: 48 89 45 e8 mov %rax,-0x18(%rbp)1175: 48 c7 45 f0 03 00 00 movq $0x3,-0x10(%rbp)117c: 00 117d: 48 c7 45 f8 04 00 00 movq $0x4,-0x8(%rbp)1184: 00 1185: 48 8b 55 f8 mov -0x8(%rbp),%rdx1189: 48 8b 45 f0 mov -0x10(%rbp),%rax118d: 48 89 d1 mov %rdx,%rcx1190: 48 89 c2 mov %rax,%rdx1193: 48 8d 35 fe 0e 00 00 lea 0xefe(%rip),%rsi # 2098 <__func__.2503>119a: 48 8d 3d 67 0e 00 00 lea 0xe67(%rip),%rdi # 2008 <_IO_stdin_used+0x8>11a1: b8 00 00 00 00 mov $0x0,%eax11a6: e8 a5 fe ff ff callq 1050 <printf@plt>11ab: 48 8b 55 f0 mov -0x10(%rbp),%rdx11af: 48 8b 45 f8 mov -0x8(%rbp),%rax11b3: 48 01 c2 add %rax,%rdx11b6: 48 8b 45 d8 mov -0x28(%rbp),%rax11ba: 48 01 c2 add %rax,%rdx11bd: 48 8b 45 e0 mov -0x20(%rbp),%rax11c1: 48 01 d0 add %rdx,%rax11c4: 48 89 45 f0 mov %rax,-0x10(%rbp)11c8: 48 8b 55 f0 mov -0x10(%rbp),%rdx11cc: 48 8b 45 f8 mov -0x8(%rbp),%rax11d0: 48 01 c2 add %rax,%rdx11d3: 48 8b 45 d0 mov -0x30(%rbp),%rax11d7: 48 01 c2 add %rax,%rdx11da: 48 8b 45 e8 mov -0x18(%rbp),%rax11de: 48 01 d0 add %rdx,%rax11e1: 48 89 45 f8 mov %rax,-0x8(%rbp)11e5: 90 nop11e6: c9 leaveq 11e7: c3 retq
2.3.3 执行完成之后栈帧的使用情况

3 X86_64 函数调用示例及其栈帧示意图

4 编译和反汇编的命令
4.1 编译的命令
x86_64-linux-gnu-gcc -Wl,--no-as-needed main.c -o x86_test
4.2 反汇编的命令
若是想把生成的反汇编程序保存的文件可以使用这个反汇编的命令:x86_64-linux-gnu-objdump -S -d x86_test > x86_64_test.S
x86_64-linux-gnu-objdump -S -d x86_test
相关文章:
X86_64函数调用汇编程序分析
X86_64函数调用汇编程序分析 1 X86_64寄存器使用标准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…...
Vue3【Provide/Inject】
前言 自从使用了Provide/Inject代码的组织方式更加灵活了,但是这个灵活性的增加伴随着代码容错性的降低。我相信只要是真的在项目中引入Provide/Inject的同学,一定一定有过或者正在经历下面的状况: 注入名(Injection key&#x…...
Go-Python-Java-C-LeetCode高分解法-第四周合集
前言 本题解Go语言部分基于 LeetCode-Go 其他部分基于本人实践学习 个人题解GitHub连接:LeetCode-Go-Python-Java-C Go-Python-Java-C-LeetCode高分解法-第一周合集 Go-Python-Java-C-LeetCode高分解法-第二周合集 Go-Python-Java-C-LeetCode高分解法-第三周合集 本…...
vue路由
一、声明式导航-导航链接 1.需求 实现导航高亮效果 如果使用a标签进行跳转的话,需要给当前跳转的导航加样式,同时要移除上一个a标签的样式,太麻烦!!! 2.解决方案 vue-router 提供了一个全局组件 router…...
最强的AI视频去码图片修复模型:CodeFormer
目录 1 CodeFormer介绍 1.1 CodeFormer解决的问题 1.2 人脸复原的挑战 1.3 方法动机 1.4 模型实现 1.5 实验结果 2 CodeFormer部署与运行 2.1 conda环境安装 2.2 运行环境构建 2.3 模型下载 2.4 运行 2.4.1 人脸复原 编辑编辑 2.4.2 全图片增强 2.4.3 人脸颜色…...
jenkins自动化部署安装
一、准备工作 1、安装jdk # 1、下载准备jdk包(也可以用docker安装) wget ... # 2、直接解压到,无需安装 unzip ...2、安装maven # 1、下载准备maven压缩包 wget ... # 2、直接解压,无需安装 unzip ... # 3、修改setting.xml,修改localRepository和MIRROR镜像地址…...
如何调用Zabbix API获取主机信息
自Zabbix 1.8版本被引进以后,Zabbix API开始扮演着越来越重要的角色,它可以为批量操作、第三方软件集成以及其他应用提供可编程接口。 在运维实践中,Zabbix API还有更多巧妙的应用。 面对规模庞大的监控设备,可能会出现某台机器发…...
批量执行redis命令总结
目录 批量执行redis命令方式1: redis-cli直接执行方式2:通过redis-cli和xargs等命令 批量执行redis命令 方式1: redis-cli直接执行 redis-cli command param redis-cli本身支持单个命令执行省略了连接参数操作的key等相关数据,可以通过线下获取或通过keys scan等命…...
命令行git联网失败,但是实际可以联网
最近下载代码的时候发现总是告诉我连不上github的网页,但是我自己通过浏览器又可以上网,找了半天发现这个方法可以。 记录下这个代理 打开git bash 执行以下命令: git config --global http.proxy http://127.0.0.1:7890 git config --glob…...
网络编程套接字,Linux下实现echo服务器和客户端
目录 1、一些网络中的名词 1.1 IP地址 1.2 端口号port 1.3 "端口号" 和 "进程ID" 1.4 初始TCP协议 1.5 UDP协议 2、socket编程接口 2.1 socket 常见API 2.2 sockaddr结构 3、简单的网络程序 3.1 udp实现echo服务器和客户端 3.1.1 echo服务器实…...
java+ssh+mysql智能化办公管理系统
项目介绍: 本系统为基于jspsshmysql的OA智能办公管理系统,包含管理员、领导、员工角色,功能如下: 管理员:公告信息;工作计划;公司资料;部门管理;员工管理;员…...
网络层抓包tcpdump
sudo tcpdump -i eth0 -s 0 -nn host iphost -w xxx.pcap 这段代码使用了命令行工具 tcpdump,用于在Linux系统上捕获网络数据包。让我详细介绍一下这段代码的含义和 tcpdump 的用法: 代码含义: sudo: 使用超级用户权限执行 tcpdump 命令&am…...
QT之形态学操作
形态学操作包含以下操作: 腐蚀 (Erosion)膨胀 (Dilation)开运算 (Opening)闭运算 (Closing)形态梯度 (Morphological Gradient)顶帽 (Top Hat)黑帽(Black Hat) 其中腐蚀和膨胀操作是最基本的操作,其他操作由这两个操作变换而来。 腐蚀 用一个结构元素…...
15、监测数据采集物联网应用开发步骤(11)
源码将于最后一遍文章给出下载 监测数据采集物联网应用开发步骤(10) 程序自动更新开发 前面章节写了部分功能模块开发: 日志或文本文件读写开发;Sqlite3数据库读写操作开发;定时器插件化开发;串口(COM)通讯开发;TCP/IP Client开发;TCP/IP Server 开发;modbus协议…...
Pygame中Trivia游戏解析6-2
3.1.2 读取保存题目的文件 在Trivia类的__init__()方法中,对各变量初始化完成之后,读取保存题目的文件,代码如下所示。 f open(filename, "r", encodingutf8) trivia_data f.readlines() f.close() 其中,open()函数…...
java 实现命令行模式
命令模式是一种行为设计模式,它允许您将请求封装为对象,以便您可以将其参数化、队列化、记录和撤销。在 Java 中实现命令模式涉及创建一个命令接口,具体命令类,以及一个接收者类,该接收者类执行实际操作。下面是一个简…...
A - Orac and Models(最长上升子序列——加强版)
There are nn models in the shop numbered from 11 to nn, with sizes s_1, s_2, \ldots, s_ns1,s2,…,sn. Orac will buy some of the models and will arrange them in the order of increasing numbers (i.e. indices, but not sizes). Orac thinks that the obtai…...
【python手写算法】逻辑回归实现分类(含公式推导)
公式推导: 代码实现: # codingutf-8 import matplotlib.pyplot as plt import numpy as npdef f(w1,x1,w2,x2,b):zw1*x1w2*x2breturn 1/(1np.exp(-z)) if __name__ __main__:X1 [12.46, 0.25, 5.22, 11.3, 6.81, 4.59, 0.66, 14.53, 15.49, 14.43,2.1…...
【2023高教社杯数学建模国赛】ABCD题 问题分析、模型建立、参考文献及实现代码
【2023高教社杯数学建模国赛】ABCD题 问题分析、模型建立、参考文献及实现代码 1 比赛时间 北京时间:2023年9月7日 18:00-2023年9月10日20:00 2 思路内容 可以参考我提供的历史竞赛信息内容,最新更新我会发布在博客和知乎上,请关注我获得最…...
yum安装mysql5.7散记
## 数据源安装 $ yum -y install wget $ wget http://dev.mysql.com/get/mysql57-community-release-el7-8.noarch.rpm $ yum localinstall mysql57-community-release-el7-8.noarch.rpm $ yum repolist enabled | grep "mysql.*-community.*" $ yum install mysql-…...
多云管理“拦路虎”:深入解析网络互联、身份同步与成本可视化的技术复杂度
一、引言:多云环境的技术复杂性本质 企业采用多云策略已从技术选型升维至生存刚需。当业务系统分散部署在多个云平台时,基础设施的技术债呈现指数级积累。网络连接、身份认证、成本管理这三大核心挑战相互嵌套:跨云网络构建数据…...
大数据学习栈记——Neo4j的安装与使用
本文介绍图数据库Neofj的安装与使用,操作系统:Ubuntu24.04,Neofj版本:2025.04.0。 Apt安装 Neofj可以进行官网安装:Neo4j Deployment Center - Graph Database & Analytics 我这里安装是添加软件源的方法 最新版…...
rknn优化教程(二)
文章目录 1. 前述2. 三方库的封装2.1 xrepo中的库2.2 xrepo之外的库2.2.1 opencv2.2.2 rknnrt2.2.3 spdlog 3. rknn_engine库 1. 前述 OK,开始写第二篇的内容了。这篇博客主要能写一下: 如何给一些三方库按照xmake方式进行封装,供调用如何按…...
前端倒计时误差!
提示:记录工作中遇到的需求及解决办法 文章目录 前言一、误差从何而来?二、五大解决方案1. 动态校准法(基础版)2. Web Worker 计时3. 服务器时间同步4. Performance API 高精度计时5. 页面可见性API优化三、生产环境最佳实践四、终极解决方案架构前言 前几天听说公司某个项…...
IGP(Interior Gateway Protocol,内部网关协议)
IGP(Interior Gateway Protocol,内部网关协议) 是一种用于在一个自治系统(AS)内部传递路由信息的路由协议,主要用于在一个组织或机构的内部网络中决定数据包的最佳路径。与用于自治系统之间通信的 EGP&…...
CMake基础:构建流程详解
目录 1.CMake构建过程的基本流程 2.CMake构建的具体步骤 2.1.创建构建目录 2.2.使用 CMake 生成构建文件 2.3.编译和构建 2.4.清理构建文件 2.5.重新配置和构建 3.跨平台构建示例 4.工具链与交叉编译 5.CMake构建后的项目结构解析 5.1.CMake构建后的目录结构 5.2.构…...
postgresql|数据库|只读用户的创建和删除(备忘)
CREATE USER read_only WITH PASSWORD 密码 -- 连接到xxx数据库 \c xxx -- 授予对xxx数据库的只读权限 GRANT CONNECT ON DATABASE xxx TO read_only; GRANT USAGE ON SCHEMA public TO read_only; GRANT SELECT ON ALL TABLES IN SCHEMA public TO read_only; GRANT EXECUTE O…...
2021-03-15 iview一些问题
1.iview 在使用tree组件时,发现没有set类的方法,只有get,那么要改变tree值,只能遍历treeData,递归修改treeData的checked,发现无法更改,原因在于check模式下,子元素的勾选状态跟父节…...
Maven 概述、安装、配置、仓库、私服详解
目录 1、Maven 概述 1.1 Maven 的定义 1.2 Maven 解决的问题 1.3 Maven 的核心特性与优势 2、Maven 安装 2.1 下载 Maven 2.2 安装配置 Maven 2.3 测试安装 2.4 修改 Maven 本地仓库的默认路径 3、Maven 配置 3.1 配置本地仓库 3.2 配置 JDK 3.3 IDEA 配置本地 Ma…...
稳定币的深度剖析与展望
一、引言 在当今数字化浪潮席卷全球的时代,加密货币作为一种新兴的金融现象,正以前所未有的速度改变着我们对传统货币和金融体系的认知。然而,加密货币市场的高度波动性却成为了其广泛应用和普及的一大障碍。在这样的背景下,稳定…...
