15 HelloWorld的字节码的编译执行的调试

news/2024/11/17 18:24:48/

前言

字节码里面隐藏了多少秘密, 呵呵 我们这里来以一个极简单的例子 来探索一下, 探索一下 基于解释执行的 相关细节 

lldb 汇编调试的部分需要感谢朋友 "新加坡买买提", 去年 12 月份的时候花了一下午的时间不佞帮助我, 呵呵 本文的例子也是那个时候 编写的以及调试的, 不过 当时是 clion 里面也能进行 lldb 的调试, 命令行中也可以, 现在 clion 里面的 lldb 不知道为啥不能调试了 ... 

 

 

测试用例

package com.hx.test02;/*** TemplateInterpreter** @author Jerry.X.He <970655147@qq.com>* @version 1.0* @date 2019-12-08 13:36*/
public class Test23TemplateInterpreter {public static void main(String[] args) {//    System.gc();int x = 1;}}

 

对应的字节码的相关信息如下, 一下可能会用于参照 

master:classes jerry$ javap -c com/hx/test02/Test23TemplateInterpreter.class 
Compiled from "Test23TemplateInterpreter.java"
public class com.hx.test02.Test23TemplateInterpreter {public com.hx.test02.Test23TemplateInterpreter();Code:0: aload_01: invokespecial #1                  // Method java/lang/Object."<init>":()V4: returnpublic static void main(java.lang.String[]);Code:0: iconst_11: istore_12: return
}

 

 

基于 lldb 的调试

(lldb) p _active_table._table[9][4]
(address) $1 = 0x0000000105830e1f "?\x01"
(lldb) p _active_table._table[9][60]
(address) $2 = 0x0000000105833aa0 "\x8b\x04$H\x83\U00000088A\x89F?A\x0f?]\x01I??I?p?0\x04\x01"
(lldb) b 0x0000000105830e1f
Breakpoint 3: address = 0x0000000105830e1f
(lldb) b 0x0000000105833aa0
Breakpoint 4: address = 0x0000000105833aa0
// iconst_1
(lldb) c
Process 3086 resuming
Process 3086 stopped
* thread #5, stop reason = breakpoint 3.1frame #0: 0x0000000105830e1f
->  0x105830e1f: movl   $0x1, %eax0x105830e24: movzbl 0x1(%r13), %ebx0x105830e29: incq   %r130x105830e2c: movabsq $0x104308a70, %r10        ; imm = 0x104308A70 
Target 0: (java) stopped.
(lldb) stepi
Process 3086 stopped
* thread #5, stop reason = instruction step intoframe #0: 0x0000000105830e24
->  0x105830e24: movzbl 0x1(%r13), %ebx0x105830e29: incq   %r130x105830e2c: movabsq $0x104308a70, %r10        ; imm = 0x104308A70 0x105830e36: jmpq   *(%r10,%rbx,8)
Target 0: (java) stopped.
(lldb) stepi
Process 3086 stopped
* thread #5, stop reason = instruction step intoframe #0: 0x0000000105830e29
->  0x105830e29: incq   %r130x105830e2c: movabsq $0x104308a70, %r10        ; imm = 0x104308A70 0x105830e36: jmpq   *(%r10,%rbx,8)0x105830e3a: nop    
Target 0: (java) stopped.
(lldb) stepi
Process 3086 stopped
* thread #5, stop reason = instruction step intoframe #0: 0x0000000105830e2c
->  0x105830e2c: movabsq $0x104308a70, %r10        ; imm = 0x104308A70 0x105830e36: jmpq   *(%r10,%rbx,8)0x105830e3a: nop    0x105830e3b: nop    
Target 0: (java) stopped.
(lldb) stepi
Process 3086 stopped
* thread #5, stop reason = instruction step intoframe #0: 0x0000000105830e36
->  0x105830e36: jmpq   *(%r10,%rbx,8)0x105830e3a: nop    0x105830e3b: nop    0x105830e3c: nop    
Target 0: (java) stopped.// istore_1
(lldb) c
Process 3086 resuming
Process 3086 stopped
* thread #5, stop reason = breakpoint 4.1frame #0: 0x0000000105833aa0
->  0x105833aa0: movl   (%rsp), %eax0x105833aa3: addq   $0x8, %rsp0x105833aa7: movl   %eax, -0x8(%r14)0x105833aab: movzbl 0x1(%r13), %ebx
Target 0: (java) stopped.
(lldb) re r
General Purpose Registers:rax = 0x0000000000000000rbx = 0x000000000000003crcx = 0x0000000000006a00rdx = 0x0000000000006a00rdi = 0x0000000105005000rsi = 0x0000000000000008rbp = 0x0000700009d05690rsp = 0x0000700009d05640r8 = 0x0000000000000000r9 = 0x0000000100611890r10 = 0x0000000104306270  libjvm.dylib`TemplateInterpreter::_normal_table + 18432r11 = 0x000000010061188cr12 = 0x0000000000000000r13 = 0x000000011c7ede61r14 = 0x0000700009d056a8r15 = 0x0000000105005000rip = 0x0000000105833aa0rflags = 0x0000000000000246cs = 0x000000000000002bfs = 0x0000000000000000gs = 0x0000000000000000(lldb) stepi
Process 3086 stopped
* thread #5, stop reason = instruction step intoframe #0: 0x0000000105833aa3
->  0x105833aa3: addq   $0x8, %rsp0x105833aa7: movl   %eax, -0x8(%r14)0x105833aab: movzbl 0x1(%r13), %ebx0x105833ab0: incq   %r13
Target 0: (java) stopped.
(lldb) re r
General Purpose Registers:rax = 0x0000000000000001rbx = 0x000000000000003crcx = 0x0000000000006a00rdx = 0x0000000000006a00rdi = 0x0000000105005000rsi = 0x0000000000000008rbp = 0x0000700009d05690rsp = 0x0000700009d05640r8 = 0x0000000000000000r9 = 0x0000000100611890r10 = 0x0000000104306270  libjvm.dylib`TemplateInterpreter::_normal_table + 18432r11 = 0x000000010061188cr12 = 0x0000000000000000r13 = 0x000000011c7ede61r14 = 0x0000700009d056a8r15 = 0x0000000105005000rip = 0x0000000105833aa3rflags = 0x0000000000000246cs = 0x000000000000002bfs = 0x0000000000000000gs = 0x0000000000000000(lldb) stepi
Process 3086 stopped
* thread #5, stop reason = instruction step intoframe #0: 0x0000000105833aa7
->  0x105833aa7: movl   %eax, -0x8(%r14)0x105833aab: movzbl 0x1(%r13), %ebx0x105833ab0: incq   %r130x105833ab3: movabsq $0x10430b270, %r10        ; imm = 0x10430B270 
Target 0: (java) stopped.
(lldb) x 0x0000700009d05640 -c 0x100
0x700009d05640: 01 00 00 00 00 00 00 00 48 56 d0 09 00 70 00 00  ........HV?..p..
0x700009d05650: 61 de 7e 1c 01 00 00 00 a8 56 d0 09 00 70 00 00  a?~.....?V?..p..
0x700009d05660: e0 de 7e 1c 01 00 00 00 00 00 00 00 00 00 00 00  ??~.............
0x700009d05670: d0 7f bb 47 07 00 00 00 88 de 7e 1c 01 00 00 00  ?.?G.....?~.....
0x700009d05680: 00 00 00 00 00 00 00 00 a8 56 d0 09 00 70 00 00  ........?V?..p..
0x700009d05690: 10 57 d0 09 00 70 00 00 f1 09 80 05 01 00 00 00  .W?..p..?.......
0x700009d056a0: 00 00 00 00 00 00 00 00 88 83 bb 47 07 00 00 00  ..........?G....
0x700009d056b0: a0 1f 00 00 03 00 00 00 00 00 00 00 00 00 00 00  ?...............
0x700009d056c0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
0x700009d056d0: 00 00 00 00 00 00 00 00 00 60 d0 09 00 70 00 00  .........`?..p..
0x700009d056e0: 20 58 d0 09 00 70 00 00 50 5d d0 09 00 70 00 00   X?..p..P]?..p..
0x700009d056f0: 0a 00 00 00 00 70 00 00 88 de 7e 1c 01 00 00 00  .....p...?~.....
0x700009d05700: 00 a7 82 05 01 00 00 00 a0 5a d0 09 00 70 00 00  .?......?Z?..p..
0x700009d05710: e0 58 d0 09 00 70 00 00 1d bb 8e 03 01 00 00 00  ?X?..p...?......
0x700009d05720: 01 00 00 00 00 70 00 00 00 50 00 05 01 00 00 00  .....p...P......
0x700009d05730: 50 57 d0 09 00 70 00 00 15 95 28 03 01 00 00 00  PW?..p....(.....
(lldb) stepi
Process 3086 stopped
* thread #5, stop reason = instruction step intoframe #0: 0x0000000105833aab
->  0x105833aab: movzbl 0x1(%r13), %ebx0x105833ab0: incq   %r130x105833ab3: movabsq $0x10430b270, %r10        ; imm = 0x10430B270 0x105833abd: jmpq   *(%r10,%rbx,8)
Target 0: (java) stopped.
(lldb) x 0x0000700009d05640 -c 0x100
0x700009d05640: 01 00 00 00 00 00 00 00 48 56 d0 09 00 70 00 00  ........HV?..p..
0x700009d05650: 61 de 7e 1c 01 00 00 00 a8 56 d0 09 00 70 00 00  a?~.....?V?..p..
0x700009d05660: e0 de 7e 1c 01 00 00 00 00 00 00 00 00 00 00 00  ??~.............
0x700009d05670: d0 7f bb 47 07 00 00 00 88 de 7e 1c 01 00 00 00  ?.?G.....?~.....
0x700009d05680: 00 00 00 00 00 00 00 00 a8 56 d0 09 00 70 00 00  ........?V?..p..
0x700009d05690: 10 57 d0 09 00 70 00 00 f1 09 80 05 01 00 00 00  .W?..p..?.......
0x700009d056a0: 01 00 00 00 00 00 00 00 88 83 bb 47 07 00 00 00  ..........?G....
0x700009d056b0: a0 1f 00 00 03 00 00 00 00 00 00 00 00 00 00 00  ?...............
0x700009d056c0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
0x700009d056d0: 00 00 00 00 00 00 00 00 00 60 d0 09 00 70 00 00  .........`?..p..
0x700009d056e0: 20 58 d0 09 00 70 00 00 50 5d d0 09 00 70 00 00   X?..p..P]?..p..
0x700009d056f0: 0a 00 00 00 00 70 00 00 88 de 7e 1c 01 00 00 00  .....p...?~.....
0x700009d05700: 00 a7 82 05 01 00 00 00 a0 5a d0 09 00 70 00 00  .?......?Z?..p..
0x700009d05710: e0 58 d0 09 00 70 00 00 1d bb 8e 03 01 00 00 00  ?X?..p...?......
0x700009d05720: 01 00 00 00 00 70 00 00 00 50 00 05 01 00 00 00  .....p...P......
0x700009d05730: 50 57 d0 09 00 70 00 00 15 95 28 03 01 00 00 00  PW?..p....(.....
(lldb) stepi
Process 3086 stopped
* thread #5, stop reason = instruction step intoframe #0: 0x0000000105833ab0
->  0x105833ab0: incq   %r130x105833ab3: movabsq $0x10430b270, %r10        ; imm = 0x10430B270 0x105833abd: jmpq   *(%r10,%rbx,8)0x105833ac1: nop    
Target 0: (java) stopped.
(lldb) stepi
Process 3086 stopped
* thread #5, stop reason = instruction step intoframe #0: 0x0000000105833ab3
->  0x105833ab3: movabsq $0x10430b270, %r10        ; imm = 0x10430B270 0x105833abd: jmpq   *(%r10,%rbx,8)0x105833ac1: nop    0x105833ac2: nop    
Target 0: (java) stopped.
(lldb) stepi
Process 3086 stopped
* thread #5, stop reason = instruction step intoframe #0: 0x0000000105833abd
->  0x105833abd: jmpq   *(%r10,%rbx,8)0x105833ac1: nop    0x105833ac2: nop    0x105833ac3: nop    
Target 0: (java) stopped.
(lldb)  

其中 0x700009d056a0 对应的数据对应的是 slot1[变量x]

可以看到这里的 iconst_1, istore_1 的大致的流程, 然后 如何存放到 slot1 里面的 

这里有一个问题就是 0x105833aa0 的地方直接使用了 栈顶的数据 放到 rax 然后进行之后的业务操作 

但是 在 iconst_1 的相关代码里面么有看到 将 rax 存入 stack 的过程(这个 push rax 在后面) 

 

 

字节码执行之间中插的代码?

在 iconst_1 和 istore_1 之间, 还执行了如下一段代码, 呵呵 有些地方看的明白, 大部分地方看不明白, 先放在这里吧, 后面 有一定的了解之后再来解惑 

(lldb) dis -s 0x105825f24 -c 200// push rax, 将1入表达式栈(这里的场景)0x105825f24: pushq  %rax// MacroAssembler::call_VM_helper0x105825f25: callq  0x105825f2f0x105825f2a: jmp    0x1058261850x105825f2f: leaq   0x8(%rsp), %rax// save_bcp0x105825f34: movq   %r13, -0x40(%rbp)// cmpptr(Address(rbp, frame::interpreter_frame_last_sp_offset * wordSize), (int32_t)NULL_WORD)0x105825f38: cmpq   $0x0, -0x10(%rbp)0x105825f40: je     0x105825fbd// ignore MacroAssembler::debug64// 擦 这里对应的是哪里 0x105825fbd: pushq  %r100x105825fbf: cmpq   -0x150f9d6(%rip), %r12    ; Universe::_narrow_ptrs_base0x105825fc6: je     0x105826043// ignore MacroAssembler::debug640x105826043: popq   %r10// LP64_ONLY(mov(c_rarg0, r15_thread))0x105826045: movq   %r15, %rdi// set_last_Java_frame(java_thread, last_java_sp, rbp, NULL);0x105826048: movq   %rbp, 0x218(%r15)0x10582604f: movq   %rax, 0x208(%r15)// MacroAssembler::call_VM_leaf_base(entry_point, number_of_arguments); 0x105826056: testl  $0xf, %esp0x10582605c: je     0x1058260740x105826062: subq   $0x8, %rsp0x105826066: callq  0x1038d5ac0               ; InterpreterRuntime::at_safepoint at interpreterRuntime.cpp:10500x10582606b: addq   $0x8, %rsp0x10582606f: jmp    0x1058260790x105826074: callq  0x1038d5ac0               ; InterpreterRuntime::at_safepoint at interpreterRuntime.cpp:1050// get_thread(java_thread);0x105826079: pushq  %rax0x10582607a: pushq  %rdi0x10582607b: pushq  %rsi0x10582607c: pushq  %rdx0x10582607d: pushq  %rcx0x10582607e: pushq  %r80x105826080: pushq  %r90x105826082: pushq  %r100x105826084: pushq  %r110x105826086: testl  $0xf, %esp0x10582608c: je     0x1058260a40x105826092: subq   $0x8, %rsp0x105826096: callq  0x103003ae0               ; Thread::current at thread.hpp:6600x10582609b: addq   $0x8, %rsp0x10582609f: jmp    0x1058260a90x1058260a4: callq  0x103003ae0               ; Thread::current at thread.hpp:6600x1058260a9: popq   %r110x1058260ab: popq   %r100x1058260ad: popq   %r90x1058260af: popq   %r80x1058260b1: popq   %rcx0x1058260b2: popq   %rdx0x1058260b3: popq   %rsi0x1058260b4: popq   %rdi0x1058260b5: cmpq   %rax, %r150x1058260b8: je     0x105826135// ignore MacroAssembler::debug640x105826135: popq   %rax// reset_last_Java_frame(java_thread, true);0x105826136: movabsq $0x0, %r100x105826140: movq   %r10, 0x208(%r15)0x105826147: movabsq $0x0, %r100x105826151: movq   %r10, 0x218(%r15)0x105826158: movabsq $0x0, %r100x105826162: movq   %r10, 0x210(%r15)// check_exceptions0x105826169: cmpq   $0x0, 0x8(%r15)0x105826171: je     0x10582617c0x105826177: jmp    0x1058007a0// restore_bcp();0x10582617c: movq   -0x40(%rbp), %r13// restore_locals();0x105826180: movq   -0x38(%rbp), %r140x105826184: retq// dispatch 下一条指令 0x105826185: movzbl (%r13), %ebx0x10582618a: movabsq $0x104306270, %r10        ; imm = 0x1043062700x105826194: jmpq   *(%r10,%rbx,8)

这块代码 主要的目的是调用 InterpreterRuntime::at_safepoint 

 

生成上面这段汇编的核心代码 似乎是来自于这里, 传入的 entry_point 是 InterpreterRuntime::at_safepoint 的 entry_point 

 

呵呵 先留在这里不求甚解吧 

 

另外还有一个现象是, 这断代码 核心调用的是 InterpreterRuntime::at_safepoint 在 lldb 命令行里面调试的时候, 你会清楚的看到 会执行这段代码, 但是 在 clion 里面调试的时候 打上一个断点, 却不会执行, 这个是和 什么时候调试 有一定的关系么 ?

 

 

这部分中插代码再记录 add at 2020.06.06

======================= add at 2020.06.06 =======================

 

今天又重新调试了一下 这个例子, 呵呵 发现了一点 之前调试记录的不同的东西 

呵呵, 有些时候 没有去 调用 InterpreterRuntime::at_safepoint 

直接按照 字节码模板 的调度过程去进行执行了, 直接以 ax 作为媒介来传递了数据 

(lldb)  p _active_table._table[9][4]
(address) $1 = 0x0000000105830e1f "?\x01"
(lldb) b 0x0000000105830e1f
Breakpoint 3: address = 0x0000000105830e1f// iconst_1
(lldb) c
Process 3326 resuming
Process 3326 stopped
* thread #5, stop reason = breakpoint 3.1frame #0: 0x0000000105830e1f
->  0x105830e1f: movl   $0x1, %eax0x105830e24: movzbl 0x1(%r13), %ebx0x105830e29: incq   %r130x105830e2c: movabsq $0x103b08a70, %r10        ; imm = 0x103B08A70
Target 0: (java) stopped.
(lldb) stepi
Process 3326 stopped
* thread #5, stop reason = instruction step intoframe #0: 0x0000000105830e24
->  0x105830e24: movzbl 0x1(%r13), %ebx0x105830e29: incq   %r130x105830e2c: movabsq $0x103b08a70, %r10        ; imm = 0x103B08A700x105830e36: jmpq   *(%r10,%rbx,8)
Target 0: (java) stopped.
(lldb) stepi
Process 3326 stopped
* thread #5, stop reason = instruction step intoframe #0: 0x0000000105830e29
->  0x105830e29: incq   %r130x105830e2c: movabsq $0x103b08a70, %r10        ; imm = 0x103B08A700x105830e36: jmpq   *(%r10,%rbx,8)0x105830e3a: nop
Target 0: (java) stopped.
(lldb) stepi
Process 3326 stopped
* thread #5, stop reason = instruction step intoframe #0: 0x0000000105830e2c
->  0x105830e2c: movabsq $0x103b08a70, %r10        ; imm = 0x103B08A700x105830e36: jmpq   *(%r10,%rbx,8)0x105830e3a: nop0x105830e3b: nop
Target 0: (java) stopped.
(lldb) stepi
Process 3326 stopped
* thread #5, stop reason = instruction step intoframe #0: 0x0000000105830e36
->  0x105830e36: jmpq   *(%r10,%rbx,8)0x105830e3a: nop0x105830e3b: nop0x105830e3c: nop
Target 0: (java) stopped.// istore_1
(lldb) stepi
Process 3326 stopped
* thread #5, stop reason = instruction step intoframe #0: 0x0000000105833aa7
->  0x105833aa7: movl   %eax, -0x8(%r14)0x105833aab: movzbl 0x1(%r13), %ebx0x105833ab0: incq   %r130x105833ab3: movabsq $0x103b0b270, %r10        ; imm = 0x103B0B270
Target 0: (java) stopped.
(lldb) stepi
Process 3326 stopped
* thread #5, stop reason = instruction step intoframe #0: 0x0000000105833aab
->  0x105833aab: movzbl 0x1(%r13), %ebx0x105833ab0: incq   %r130x105833ab3: movabsq $0x103b0b270, %r10        ; imm = 0x103B0B2700x105833abd: jmpq   *(%r10,%rbx,8)
Target 0: (java) stopped.
(lldb) stepi
Process 3326 stopped
* thread #5, stop reason = instruction step intoframe #0: 0x0000000105833ab0
->  0x105833ab0: incq   %r130x105833ab3: movabsq $0x103b0b270, %r10        ; imm = 0x103B0B2700x105833abd: jmpq   *(%r10,%rbx,8)0x105833ac1: nop
Target 0: (java) stopped.
(lldb) stepi
Process 3326 stopped
* thread #5, stop reason = instruction step intoframe #0: 0x0000000105833ab3
->  0x105833ab3: movabsq $0x103b0b270, %r10        ; imm = 0x103B0B2700x105833abd: jmpq   *(%r10,%rbx,8)0x105833ac1: nop0x105833ac2: nop
Target 0: (java) stopped.
(lldb) stepi
Process 3326 stopped
* thread #5, stop reason = instruction step intoframe #0: 0x0000000105833abd
->  0x105833abd: jmpq   *(%r10,%rbx,8)0x105833ac1: nop0x105833ac2: nop0x105833ac3: nop
Target 0: (java) stopped.

 

 

呵呵 上面的 字节码执行之间中插的代码 来自于 

 

以上两种情况对应于 active_table 为 normal_table 或者 切换为 safept_table 的情况, 呵呵 但是什么情况下切换, 目前我还不明白 

active_table 为 normal_table 的场景 

(lldb) p _active_table._table[9][194]
(address) $0 = 0x000000010604f980 "XH;"
(lldb) p _active_table._table[0][0]
(address) $1 = 0x0000000106030b9e "PA\x0f\xb6]\x01I??I\xbap\xb2\xb0\x03\x01"
(lldb) p _normal_table._table[0][0]
(address) $2 = 0x0000000106030b9e "PA\x0f\xb6]\x01I??I\xbap\xb2\xb0\x03\x01"
(lldb) p _safept_table._table[0][0]
(address) $3 = 0x00000001060252e0 "P?
(lldb) p _active_table._table[9][4]
(address) $4 = 0x0000000106030e1f "\xb8\x01"
(lldb) b 0x0000000106030e1f
Breakpoint 3: address = 0x0000000106030e1f
(lldb) c
Process 3783 resuming
Process 3783 stopped
* thread #5, stop reason = breakpoint 3.1frame #0: 0x0000000106030e1f
->  0x106030e1f: movl   $0x1, %eax0x106030e24: movzbl 0x1(%r13), %ebx0x106030e29: incq   %r130x106030e2c: movabsq $0x103b08a70, %r10        ; imm = 0x103B08A70
Target 0: (java) stopped.
(lldb) p _active_table._table[0][0]
(address) $5 = 0x0000000106030b9e "PA\x0f?]\x01I??I?p??\x03\x01"

active_table 为 safept_table 的场景 

(lldb) p _active_table._table[9][194]
(address) $0 = 0x000000010584f980 "XH;"
(lldb) p _active_table._table[0][0]
(address) $1 = 0x0000000105830b9e "PA\x0f\xb6]\x01I??I\xbap\xb20\x04\x01"
(lldb) p _normal_table._table[0][0]
(address) $2 = 0x0000000105830b9e "PA\x0f\xb6]\x01I??I\xbap\xb20\x04\x01"
(lldb) p _safept_table._table[0][0]
(address) $3 = 0x00000001058252e0 "P?
(lldb)  p _active_table._table[9][4]
(address) $4 = 0x0000000105830e1f "?\x01"
(lldb) b 0x0000000105830e1f
Breakpoint 3: address = 0x0000000105830e1f
(lldb) c
Process 3646 resuming
Process 3646 stopped
* thread #5, stop reason = breakpoint 3.1frame #0: 0x0000000105830e1f
->  0x105830e1f: movl   $0x1, %eax0x105830e24: movzbl 0x1(%r13), %ebx0x105830e29: incq   %r130x105830e2c: movabsq $0x104308a70, %r10        ; imm = 0x104308A70 
Target 0: (java) stopped.
(lldb) p _active_table._table[0][0]
(address) $5 = 0x00000001058252e0 "P?

 

 

 

 

 

完 

 

 


http://www.ppmy.cn/news/774598.html

相关文章

box-flex: 1

设置.md-f1 { box-flex: 1; -webkit-box-flex: 1; }&#xff0c;感觉没用啊可是删掉的话&#xff0c;这个div会移动到最右边。 <body class"md-box md-ver md-size"><div class"md-box box"><div class"md-box color-6 md-ac text&qu…

XBee S2C@ 802.15.4

Digi XBee 802.15.4的第一个版本也称为S1&#xff0c;是基于Freescale的无线收发器片子设计的。最新的802.15.4模块&#xff08;内部称号S1B&#xff09;采用和Digi ZigBee模块相同SOC芯片设计&#xff0c;官方的名称为XBee S2C 802.15.4和XBee PRO S2C 802.15.4。同样地&#…

2bb

参加二B补录的院校大多是民办高校或独立学院&#xff0c;考生应该首先考虑尽量抓住最后一次上本科的机会。 按照广东高考网上录取批次的安排&#xff0c;8月2日~3日将公布第二批本科B类院校未完成招生任务的专业及计划&#xff0c;组织尚未录取考生补报志愿&#xff1b;8月4日…

Atlassian JIRA 授权许可证机制分析

JIRA在Atlassian开发的各种产品中算是最著名的一个&#xff0c;它主要是用来做产品缺陷跟踪和项目管理的。JIRA是商业软件&#xff0c;它的授权是按使用用户数划分的&#xff0c;最便宜的10用户版本只要10美元&#xff0c;这极大地方便了小型团队的开发&#xff0c;不过25个用户…

【XBEE手册】XBEE操作

【XBEE手册】XBEE操作 (ZigBee)[ZigBee, XBEE手册] [转载请注明出处&#xff0c;谢谢!] 【XBEE手册】XBEE操作 串口接口UART数据流 串行数据 SPI通信 SPI操作串口选择 串口缓冲区 串口接受缓冲区串口发送缓冲区 UART流控制 CTSCTS\overline{CTS}流控制RTSRTS\overline{RTS}流…

解决\xEF\xBB\xBF问题

解决\xEF\xBB\xBF问题 参考文章&#xff1a; &#xff08;1&#xff09;解决\xEF\xBB\xBF问题 &#xff08;2&#xff09;https://www.cnblogs.com/mao2080/p/8178412.html &#xff08;3&#xff09;https://www.codeprj.com/blog/7ccaec1.html 备忘一下。

B22-9-5

假定有7个航班&#xff0c; 现在需要在某某到某某航班上增添座位&#xff0c;问怎样才是较优解。 题目&#xff1a;[2,5,3]&#xff0c;意思是在2-5的航班上&#xff0c;之间的每个航班增加三张票。 首先的步骤&#xff1a;写出1-7航班&#xff0c;并且在前后都多补充一个数&a…

ESP32-S的UART2的初始化需要注意的问题

简 介&#xff1a; 在使用ESP32-S的UART2的时候&#xff0c;初始化UART的ID需要设置成1&#xff0c;而不是2&#xff0c;这样可以避免ESP32热启动出现故障。具体原因并不清楚&#xff0c;但可以解决热启动程序执行的问题。在MicroPython输出汉字的时候&#xff0c;需要预先将汉…