安全基礎學習-keil調試匯編代碼

初始目的是為了通過匯編編寫CRC功能。
但是基礎為0,所以目前從搭建工程開始記錄。
大佬繞路。

(一)創建項目

1. 新建項目

  1. 打開 Keil uVision。
  2. 選擇 Project -> New uVision Project 創建一個新項目。
  3. 選擇你的目標設備(如 ARM Cortex-M 系列處理器),我這里一開始選擇的M0,后面因為報錯改為了M3。

2. 新建匯編文件

  1. 在項目中,右鍵點擊 Source Group 1,選擇 Add New Item to Group ‘Source Group 1’。
  2. 選擇 Assembler Source File,命名文件并點擊 Add。

3. 編寫匯編代碼

```asmAREA    MyCode, CODE, READONLYENTRYEXPORT  __main__main  MOV     R0, #0x10     ; 將立即數 0x10 加載到 R0 寄存器MOV     R1, #0x20     ; 將立即數 0x20 加載到 R1 寄存器ADD     R2, R0, R1    ; 將 R0 和 R1 相加,結果存入 R2B       .            ; 無限循環END
```

4. 配置啟動文件

確保項目中包含正確的啟動文件(startup file),這對于 ARM Cortex-M 項目來說非常重要。你可以在目標設備的 Startup 文件夾中找到適合的啟動文件并將其添加到項目中。
在這里插入圖片描述

5. 編譯項目

1.點擊 Project -> Build Target 或按快捷鍵 F7 進行編譯。
2.如果有編譯錯誤,修復后重新編譯。

6. 加載并調試代碼

  1. 配置模擬器:

    • 選擇 Options for Target ‘Target 1’(點擊工具欄中的扳手圖標)。
    • 在 Debug 選項卡中,選擇 Use Simulator。
    • 點擊 OK 保存配置。
      在這里插入圖片描述
  2. 進入調試模式:

    • 點擊 Debug -> Start/Stop Debug Session 或按快捷鍵 Ctrl+F5 進入調試模式。
    • Keil 將啟動模擬器,你可以看到一個新的調試窗口。
  3. 調試代碼:

    • 使用調試工具欄中的按鈕進行代碼的單步執行(Step Over/F10, Step Into/F11)、設置斷點(在代碼行左側點擊)和觀察寄存器、內存等。
    • 在調試窗口中,可以使用 Watch 窗口查看變量和寄存器的值。
    • 使用 Memory 窗口查看特定內存地址的內容。
    • 使用 Register 窗口查看和修改 CPU 寄存器的值。

(二)Disassembly窗口解釋

  • 地址列(Address):
    這一列顯示了每條匯編指令在內存中的地址。地址是十六進制格式,表示當前指令在程序內存中的位置。這有助于你了解代碼在內存中的分布以及調試時的具體位置。

  • 機器碼列(Machine Code / Opcode):
    這一列顯示了每條匯編指令對應的機器碼(十六進制格式)。它展示了 CPU 執行指令時實際處理的字節碼。對于調試和分析底層行為非常有用。

  • 匯編指令列(Disassembly / Instruction):
    這一列顯示了指令的匯編語言格式。它展示了 CPU 執行的指令以及它們的操作數。你可以看到每條指令的操作碼和操作數,例如 MOV R0, #1 或 ADD R1, R2。

  • 源代碼列(Source Code)(如果有):
    如果你的工程配置了源代碼文件,并且源代碼與匯編指令有映射關系,Disassembly 窗口可能會顯示源代碼行號和代碼內容。這列幫助你將匯編代碼與對應的高層源代碼關聯起來。

  • 符號列(Symbol)(如果啟用):
    這列可能顯示符號信息,例如函數名或變量名。在某些設置中,你可以看到每條匯編指令的符號名稱,這對于理解代碼的功能和調試非常有幫助。

Address   Machine Code     Disassembly            Source Code
08000000  E3A00001        MOV R0, #1              // int x = 1;
08000004  E0801003        ADD R1, R0, R3
  • Address:08000000 是 MOV R0, #1 指令的內存地址。
  • Machine Code:E3A00001 是 MOV R0, #1 指令的機器碼。
  • Disassembly:MOV R0, #1 是指令的匯編語言表示。
  • Source Code:如果有源代碼文件,這一列顯示了相關的源代碼行(如 int x = 1;)。

(三)寄存器窗口

在寄存器窗口中,通常會顯示以下信息:

  • 寄存器名稱(Register Name):
    顯示寄存器的名稱。常見的寄存器名稱包括 R0、R1、PC(程序計數器)、SP(棧指針)、LR(鏈接寄存器)等。不同的微控制器架構可能有不同的寄存器集合。

  • 寄存器值(Value):
    顯示每個寄存器當前的值,通常以十六進制格式表示。這些值是 CPU 當前使用的寄存器內容。

使用寄存器窗口

  • 查看寄存器值:
    在寄存器窗口中,可以看到所有寄存器的當前值。

  • 修改寄存器值:
    有些調試器允許手動修改寄存器的值。可以在寄存器值欄中直接輸入新的值并按 Enter 鍵來修改,例如可以修改程序計數器(PC)以改變程序的執行流。

  • 同步查看:
    寄存器窗口通常會自動更新顯示寄存器的最新值。當程序執行或暫停時,可以看到寄存器值的變化。

Register    Value
---------------------
R0          0x00000010
R1          0x00000020
R2          0x00000030
PC          0x08000000
SP          0x20001000
LR          0x08000010

R0:寄存器 R0 的值是 0x00000010。
PC:程序計數器 PC 的值是 0x08000000,表示當前正在執行的指令地址。
SP:棧指針 SP 的值是 0x20001000,表示當前棧的頂部地址。

(四)Program Size

Program Size: Code=544 RO-data=268 RW-data=4 ZI-data=3445

Program Size 是指編譯和鏈接后的程序代碼和數據在目標微控制器(如 ARM Cortex-M)中所占用的存儲空間。它主要由以下幾個部分組成:

1. Code Size (代碼大小)

這是指程序中所有的指令(即代碼段 .text)在目標設備閃存中所占用的空間。它包括用戶編寫的代碼、庫函數、以及編譯器生成的代碼。
影響因素:代碼優化級別、函數的復雜度、庫函數的使用情況、內聯函數(inline functions)等。

2. RO Data Size (只讀數據大小)

這是指所有只讀數據(即 .rodata 段)在閃存中所占用的空間。這些數據包括常量字符串、只讀變量、編譯時確定的初始化數據等。
影響因素:程序中定義的常量、字符串以及所有使用 const 修飾的變量。

3. RW Data Size (讀寫數據大小)

這是指可讀寫數據段(即 .data 段)在閃存和 SRAM 中所占用的空間。它包括全局變量和靜態變量(靜態分配的),這些變量在程序啟動時由閃存中的初始化數據拷貝到 SRAM 中。
影響因素:全局變量、靜態變量的數量和類型,以及這些變量的初始值。

4. ZI Data Size (零初始化數據大小)

這是指未初始化的全局變量和靜態變量(即 .bss 段)在 SRAM 中所占用的空間。在程序啟動時,這些變量會被初始化為零,因此在閃存中不占用空間。
影響因素:未初始化的全局變量和靜態變量的數量和類型。

5. Stack Size (堆棧大小)

堆棧用于存儲函數調用時的局部變量、返回地址、中斷處理器上下文等。它位于 SRAM 中,但在 Program Size 報告中通常不會直接顯示。
影響因素:遞歸調用深度、函數中局部變量的數量和大小、中斷服務程序的嵌套層次等。

6. Heap Size (堆大小)

堆用于動態內存分配(如 malloc),位于 SRAM 中。在 Program Size 報告中通常也不會直接顯示,但它的大小會影響 SRAM 的總體使用情況。
影響因素:動態內存分配的需求,程序運行時的內存分配策略。

7. 總大小 (Total Size)

這是代碼、只讀數據、讀寫數據和零初始化數據段的總和,通常是需要在閃存和 SRAM 中分配的總空間。對于嵌入式系統,優化代碼大小以符合設備的存儲限制是非常重要的。

(五)map文件

1. 總空間大小分配

  Code (inc. data)   RO Data    RW Data    ZI Data      Debug   11720       1356       1268        108       1388     267457   Grand Totals11720       1356       1268        108       1388     267457   ELF Image Totals11720       1356       1268        108          0          0   ROM Totals==========================================================================Total RO  Size (Code + RO Data)                12988 (  12.68kB)
Total RW  Size (RW Data + ZI Data)              1496 (   1.46kB)
Total ROM Size (Code + RO Data + RW Data)      13096 (  12.79kB)

KEIL編譯器會在每次編譯和鏈接后生成一個 map 文件,其中詳細列出了程序中每個段的大小,以及每個段在閃存和 SRAM 中的具體分布情況。

RO Size (Code + RO Data) ,表示程序占用Flash空間的大小。RW Size (RW Data + ZI Data),表示運行時占用的RAM的大小。ROM Size (Code + RO Data + RW Data) ,表示燒寫程序占用的Flash空間的大小。

在這里插入圖片描述

2. Memory Map of the image

打開.map文件,找到Memory Map of the image即可查看對應的內存分配。

1. Exec Addr (執行地址)

  • 定義:這是程序代碼或數據在運行時的執行地址,即程序運行時,該部分代碼或數據會被映射到這個地址。
  • 用途:確定程序在內存中實際運行的地址,通常用于區分代碼的執行位置(如在閃存中)和數據的運行位置(如在 SRAM 中)。

2. Load Addr (加載地址)

  • 定義:這是程序或數據在加載時的地址,即當程序加載到內存中時,該段最初被存儲的地址。
  • 用途:加載地址通常用于初始化數據時。對于代碼段,加載地址和執行地址通常是相同的;但對于初始化的數據段,加載地址通常在閃存中,而執行地址在 SRAM 中。

3. Size (大小)

  • 定義:表示該段占用的內存大小,通常以字節為單位。
  • 用途:用于確定每個段占用了多少內存空間,便于內存布局優化。

4. Type (類型)

  • 定義:標識該段的類型,通常包括 Code、Data 等類型。
    用途:
  • Code:表示這部分是代碼段。
  • Data:表示這部分是數據段(包括初始化數據和未初始化數據)。

5. Attr (屬性)

  • 定義:標識該段的屬性,通常是一個或多個字符組合,如 RO(只讀),RW(讀寫),ZI(零初始化)。
    用途:
  • RO:只讀數據,如常量或代碼。
  • RW:可讀寫數據,如初始化的全局變量。
  • ZI:零初始化數據段,通常是未初始化的全局變量。

6. Idx (索引)

  • 定義:這是該段在 MAP 文件中的索引號,用于區分和標識不同的段。
  • 用途:可以幫助開發者快速定位和參考特定的段信息。

7. Section Name (段名稱)

  • 定義:表示該段在源文件中的名稱,如 .text(代碼段)、.data(數據段)、.bss(未初始化數據段)等。
  • 用途:段名稱幫助識別該段屬于哪個類型和功能,便于調試和優化。

8. Object (對象)

  • 定義:表示該段所屬的目標文件(通常是 .o 文件),即該段是由哪個源文件生成的。
  • 用途:幫助開發者了解代碼和數據是從哪個源文件或庫生成的,以便進行進一步的分析和優化。

示例解釋

假設 MAP 文件中有如下條目:

Exec Addr  Load Addr   Size     Type   Attr  Idx  E Section Name  Object
0x08000000 0x08000000  0x00000400  Code  RO    1    .text          main.o
0x20000000 0x08000400  0x00000020  Data  RW    2    .data          main.o
0x20000020 0x20000020  0x00000100  Data  ZI    3    .bss           main.o
  1. 第1行:

    • Exec Addr 和 Load Addr:0x08000000,表示代碼段 .text 在加載和執行時都在這個地址(通常是閃存)。
    • Size:0x400 字節,即 1024 字節。
    • Type:Code,表示這是代碼段。
    • Attr:RO,表示該段是只讀的。
    • Section Name:.text,表示這是代碼段。
    • Object:main.o,表示這是從 main.o 文件中生成的段。
  2. 第2行:

    • Exec Addr:0x20000000,表示這個數據段在執行時位于 SRAM 中。
    • Load Addr:0x08000400,表示數據的初始值存儲在閃存中(通常在程序啟動時會從閃存加載到 SRAM)。
    • Size:0x20 字節,即 32 字節。
    • Type:Data,表示這是數據段。
    • Attr:RW,表示該段是可讀寫的。
    • Section Name:.data,表示這是初始化數據段。
    • Object:main.o,表示這是從 main.o 文件中生成的段。
  3. 第3行:

    • Exec Addr 和 Load Addr:0x20000020,表示這個段在 SRAM 中,且未初始化(因此不占用閃存)。
    • Size:0x100 字節,即 256 字節。
    • Type:Data,表示這是數據段。
    • Attr:ZI,表示這是零初始化段。
    • Section Name:.bss,表示這是未初始化數據段。
    • Object:main.o,表示這是從 main.o 文件中生成的段。

(六)keil的memory中顏色的區別

KEIL IDE 中,Memory 視圖使用顏色來表示不同類型的內存區域或數據。

1. 黃色 (Yellow)

  • 含義:黃色通常表示 已分配的代碼段 或 只讀數據。
  • 用途:在 Flash 中,這通常是代碼 (.text 段) 或者是只讀常量數據 (.rodata 段),這些內容在程序運行時不會被修改。
  • 例子:程序的指令集、常量字符串、const 變量等。

2. 綠色 (Green)

  • 含義:綠色通常表示 已分配的可讀寫數據段。
  • 用途:在 SRAM 中,這通常是已初始化的全局變量和靜態變量 (.data 段),以及動態分配的內存(如堆或棧)。
  • 例子:全局變量、靜態變量、初始化的數組或結構體等。

3. 黑色 (Black):

  • 含義:表示未使用或未分配的內存空間。
  • 用途:在這種區域內存并未被當前的程序占用,可能在某些情況下可用于動態分配(如堆的擴展)或供其他用途。
  • 位置:這種顏色通常出現在內存映射中未被分配的區域,包括 Flash、SRAM 等。

總結

  • 黃色:表示代碼或只讀數據,通常位于 Flash 中,不會在運行時改變。
  • 綠色:表示可讀寫的數據段,通常位于 SRAM 中,可以在運行時修改。
  • 黑色:表示未分配的內存區域,內存視圖中這些部分是空閑的,沒有被程序使用或初始化。

顏色變化

在 KEIL 的內存視圖中,黃色 和 綠色 的變化通常與內存的使用狀態和訪問權限有關。雖然黃色通常表示只讀內容,如代碼段或只讀數據段,但有時候這些段會在程序運行時被修改,導致它們的狀態發生變化。這種變化可能反映為顏色從黃色變為綠色。

可能的原因包括:

  1. 內存重定位或重寫:
    某些情況下,代碼或只讀數據段在運行時可能會被重新加載或重寫。例如,某些嵌入式系統中,可能會使用自編程技術動態修改程序的某些部分,這可能導致這些段的狀態從只讀變為可寫。
  2. 調試器的視角:
    在調試過程中,調試器可能會修改某些內存區域,特別是在使用斷點或修改內存時。調試器可能將某些內存段標記為可寫(綠色),即使它們在正常情況下是只讀的(黃色)。這種情況尤其常見于調試初始化數據或調試代碼時。
  3. 運行時狀態改變:
    一些系統在啟動時會將某些內存段從只讀狀態轉換為可寫狀態。例如,啟動時初始化數據段可能會從閃存(只讀,黃色)復制到 SRAM(可寫,綠色),以便程序運行時修改這些數據。
    調試工具的內存可視化更新:

在調試過程中,內存視圖會動態更新,顯示當前內存的狀態。如果調試器檢測到某段內存的訪問權限發生了變化(例如從只讀變為讀寫),顏色也會相應更新。

問題記錄

1. error: A1859E: Flag preserving form of this instruction not available

解決方法

(1)MOV等命令加上s

在這里插入圖片描述

(2)更改為M3(一開始使用的M0)

在這里插入圖片描述

2.Error: L6218E: Undefined symbol Image$$ARM_LIB_STACK$$ZI$$Limit (referred form startup_armcm3.o).

因為 armclang 默認不勾選 Use Memory Layout from Target Dialog 選項,因此必須要手動添加鏈接腳本,即分散加載文件。通過下拉框,直接使用默認的鏈接腳本即可。
在這里插入圖片描述
這里記得選擇M3對應的。圖片是借鑒的其他人的。

3.不同group見互相include文件失敗

選擇 Options for Target。
配置包含路徑:

  • 在彈出的對話框中,選擇 C/C++ 選項卡。
  • 在 Include Paths 輸入框中添加包含頭文件的路徑。

3. error 65: access violation at xxx : no 'read' permission

通常表示匯編代碼中嘗試訪問未授權或不存在的內存區域。這個錯誤常見于訪問無效的地址或指令地址不正確。

檢查內存訪問

  • 訪問的地址是否有效:
    確保你讀取和寫入的內存地址在有效范圍內。特別是訪問寄存器或數據結構時,確保地址正確。

  • 棧操作:
    如果你從棧中讀取參數,確保棧指針 SP 的位置正確。訪問棧空間時,地址應該是相對于棧指針的正確偏移量。

4.Note: source file ‘..\xx\cxx\xx.c‘ -object file renamed from “xx.o“ to “xx_1.o“

原因

使用keil添加文件時,在不同的group文件夾里添加了兩個相同的.c文件,會導致編譯出現如上的提示,即同一個c源文件,在不同的文件夾下,被添加了多次。

解決辦法

(1)反復rebuild
  1. 刪除重復文件
  2. 在對應重復的文件上右鍵“Options for File ‘xxx.c’…”,取消"include in Target Build"處的勾選,點擊“OK”后,rebuild
    在這里插入圖片描述
    這一步不管報錯與否都不用管
  3. 再次勾選上,rebuild

雖然這個方法沒有解決我的問題,但是很多人好像可以解決,用以參考

(2)重命名

我的group下,.c,.h.s都是一個名字,更改.s名字后不報錯

5.關于寄存器讀取字節順序問題

我做到cr64時,需要分別讀取內存中的高 32 位和低 32 位的 CRC 多項式。然而,讀取的順序可能會受到系統的字節序影響。

字節序 (Endianness) 是決定多字節數據在內存中存儲順序的系統特性,有兩種常見的字節序:

  • 大端序 (Big-endian): 高字節存儲在低地址,低字節存儲在高地址。
  • 小端序 (Little-endian): 低字節存儲在低地址,高字節存儲在高地址。

ARM 處理器可以支持這兩種字節序,但默認情況下大多數 ARM 設備使用小端序。這意味著在內存中存儲的數據順序可能與我們在代碼中預期的順序相反。

  • 假設你的系統是小端序
    例如,如果內存中存儲的 64 位數0x42F0E1EBA9EA3693是按小端序排列的,它在內存中的布局將是:
內存地址:    低地址 --> 高地址
數據:       93 36 EA A9 EB E1 F0 42

6.不能用M3的核,必須用M0的,接下來記錄改為M0的一些修改

6.1 Error: 1874E: Specified register list cannot be loaded or stored in target instruction setxxx

這個問題由于我PUSH和POP超過了R4-R7,改為PUSH{R4-R7, LR}即可

pop的時候也要注意,不能直接popLR
需要

POP {R4-47}
POP {R3}
MOV PC, R3

6.2其他寄存器使用問題

用M0的核的話,大部分的指令只能訪問R4-R7,少部分指令如MOV可訪問高位寄存器R8-R12.這里整個重新規劃寄存器的使用

6.3指令變體

Cortex-M0架構中,某些指令的變體(如設置條件標志的變體)可能不可用,例如ADD指令在設置條件標志時可能需要用ADDS。
ADDS、MOVS、SUBS、LSLS、ANDS和ORRS指令:這些指令不僅執行算術或邏輯操作,還會根據結果自動更新條件標志位。使用這些指令可以替代標準的ADD、MOV、SUB、LSL、AND和ORR指令,以確保符合Cortex-M0架構的指令集。

如MOV立即數需要用MOVS,而寄存器則仍然可以使用MOV

6.4 LDRB自增

LDRB R4, [R5], #1

數據讀取與地址更新分離:
LDRB R4, [R5], #1指令分成兩步:

  1. 先用LDRB R4, [R5]讀取字節
  2. 再用ADDs R5, R5, #1更新指針R5。
    這樣可以避免在Cortex-M0架構中出現的尋址模式不支持問題。

6.5 BIC R0, R0, #0x100清零問題

Cortex-M0架構不支持BIC指令直接處理立即數超過8位。
對于BIC R0, R0, #0x100這行代碼,可以通過邏輯與的方式替換為:

ANDS R0, R0, #0xFF  ; 保留低8位,將高位清零

這行指令會將R0的高位清零,僅保留低8位。這樣做可以達到與BIC R0, R0, #0x100相同的效果,同時適用于Cortex-M0架構。

6.6 CRC16的最高位清零問題

immediate 0x0000ffff out of range for this operation,permintted values are 0x00000000 to 0x000000FF
在ARM的Thumb指令集中(比如Cortex-M0),ANDS指令只允許使用8位以內的立即數(0x00到0xFF)。但是嘗試使用的立即數是0xFFFF,超出了這個范圍,所以會報錯。

可以通過先用MOVS指令將0xFFFF加載到一個寄存器,然后再使用ANDS指令來解決這個問題。

MOVS R2, #0xFF     ; 將0xFF加載到R2
LSLS R2, #8        ; 將R2左移8位,得到0xFF00
ADDS R2, R2, #0xFF ; 加上0xFF,得到0xFFFF
ANDS R0, R2        ; 將R0和R2進行按位與運算

6.7 LDRB R5, [R4, #48],m0核報錯,data transfer offset 0x00000030out of range,permitter values are 0x00000000 to 0x0000001F

在 ARM Cortex-M0 架構中,數據傳輸指令(如 LDRB)的偏移量限制在 5 位以內,也就是 0x00 到 0x1F(十進制 0 到 31)。當偏移量超過這個范圍時,會報錯。

如果需要使用更大的偏移量,可以通過多次累加的方式來實現。比如,可以先將偏移量分成多步,或者先將基址寄存器加上偏移量,再執行加載指令。

解決方法
1. 分段加偏移:

可以先對寄存器進行加法運算,然后再使用 LDRB 指令。

ADDS R4, R4, #32    ; 先加32,使偏移量小于32
LDRB R5, [R4, #16] ; 現在的偏移量是16,總偏移量是48
2. 直接調整基址寄存器:

可以將偏移量直接添加到基址寄存器,然后進行加載操作。

ADDS R4, R4, #48    ; 將R4加上48,偏移基址
LDRB R5, [R4, #0]  ; 使用偏移量為0的LDRB指令

6.8 復合語句拆分

ORR R0, R0, R1, LSR #31 這種形式的操作可能會報錯,因為Cortex-M0處理器在Thumb指令集中不支持使用立即數位移的形式。可以通過分步操作來實現這一功能。具體實現如下:

LSRS R1, R1, #31  ; 將R1邏輯右移31位,將結果存入R1
ORRS R0, R0, R1   ; 將R0和R1按位或,結果存入R0

7. 無法查看匯編返回結果

如果result是局部變量,有時調試器可能不容易顯示其值。可以將result聲明為全局變量來確保它在調試器中容易被訪問。

volatile int result;  // 全局變量,確保在調試器中可見int main() {result = add(3, 4);  // 調用匯編函數while(1);  // 用于暫停程序在此處,方便調試器檢查變量值
}

參考鏈接

以上很多圖片由于keil不在當前電腦,圖片大部分借用的其他人的。
參考鏈接1
參考鏈接2
參考鏈接3
參考鏈接4
參考鏈接5

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/web/62765.shtml
繁體地址,請注明出處:http://hk.pswp.cn/web/62765.shtml
英文地址,請注明出處:http://en.pswp.cn/web/62765.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

安裝qt 5.15.2筆記

撰文是2024年12月 最終實現了 1、用梯子下載了離線包5.14.2,最后沒用 2、用內地鏡像在線安裝5.15.2,3分鐘裝完 正文開始,qt官方簡稱官方。 官方包官方自5.15.X起,不再提供的exe/run安裝包https://download.qt.io/archive/qt/ …

Redis Java 集成到 Spring Boot

Hi~!這里是奮斗的明志,很榮幸您能閱讀我的文章,誠請評論指點,歡迎歡迎 ~~ 🌱🌱個人主頁:奮斗的明志 🌱🌱所屬專欄:Redis 📚本系列文章為個人學習筆…

【Syncfusion系列】Diagram 雜談 第三篇 序列化和反序列化

目錄 序列化保存C# 代碼示例, 方式1 :C# 代碼示例, 方式2 : 反序列化加載C# 代碼示例, 方式1:C# 代碼示例, 方式2: **如何序列化自定義屬性**序列化和反序列化都存在的一個問題解決方式 圖表是否已修改&…

麒麟信安推出支持信創PC的新一代云桌面方案,助力政務信創高效安全運維

12月11日,在第二屆國家新一代自主安全計算系統產業集群融通生態大會上,麒麟信安發布了支持信創PC的新一代云桌面方案,該方案是基于國際TCI架構實現國產PC機云化納管在國內的首次發布,并與銀河麒麟桌面操作系統、長城國產PC整機實現…

中國科學院2001年數據結構試題

一、單項選擇題(每空2分,共20分) 1.下列函數中漸近時間復雜度最小的是( )。 A.T1(n)nlog2n5000n B.T2(n)n2-8000n C.T3(n)nlog221-6000n D.T4(n)2nlog2n-7000n 2.線性表的靜態鏈表存儲結構與順序…

MySQL數據表記錄刪操作

刪除操作:作用刪除表里的記錄行(都是整行整行的刪除的) 1.單表的刪除 語法 delete from 表名 where 要刪除的記錄篩選條件; 案例:刪除員工編號大于203的員工信息 delete from employees where employee_id>203; 2.多表的刪除…

網絡原理04

可靠傳輸,是TCP最核心的特性 可靠傳輸不是說數據100%傳輸給接收方了 1)發送方發出數據后,能過知道接收方是否收到數據 2)一旦發現對方沒收到,可以通過一定的方法”補救” 1. 確認應答 發送方,把數據已…

微信小程序5-圖片實現點擊動作和動態加載同類數據

搜索 微信小程序 “動物覓蹤” 觀看效果 感謝閱讀,初學小白,有錯指正。 一、功能描述 a. 原本想通過按鈕加載背景圖片,來實現一個可以點擊的搜索button,但是遇到兩個難點,一是按鈕大小調整不方便(網上搜索…

Java里局部變量和成員變量的隱式初始化

注:本文是對另一篇文檔( https://blog.csdn.net/duke_ding2/article/details/142365872 )的補充。 文章目錄 環境初始化局部變量(棧)成員變量(堆)其它數組 分析安全性性能成員變量 VS. 局部變量…

孚盟云 MailAjax.ashx SQL注入漏洞復現

0x01 產品簡介 上海孚盟軟件有限公司是一家外貿SaaS服務提供商,也是專業的外貿行業解決方案專業提供商。 全新的孚盟云產品,讓用戶可以用云模式實現信息化管理,讓用戶的異地辦公更加流暢,大大降低中小企業在信息化上成本,用最小的投入享受大型企業級別的信息化服務,主要…

“切片賦值”創建列表批量操作“新”方法(Python)

[start:end]切片賦值,擴展了list批量增減元素的操作能力。 (筆記模板由python腳本于2024年12月06日 15:07:56創建,本篇筆記適合研python基礎的coder翻閱) 【學習的細節是歡悅的歷程】 Python 官網:https://www.python.org/ Free:…

LabVIEW實現GPS通信

目錄 1、GPS通信原理 2、硬件環境部署 3、程序架構 4、前面板設計 5、程序框圖設計 6、測試驗證 本專欄以LabVIEW為開發平臺,講解物聯網通信組網原理與開發方法,覆蓋RS232、TCP、MQTT、藍牙、Wi-Fi、NB-IoT等協議。 結合實際案例,展示如何利用LabVIEW和常用模塊實現物聯網系…

Java簡介:打開通往變成世界的大門

Java是什么?為什么它是全球開發者廣泛使用的語言?本篇文章介紹Java的特點、應用場景以及“寫一次,隨處運行”的核心特性,讓零基礎的你建立對Java語言的初步認知。 注:此文章可以僅作了解,不影響之后的學習。…

Unraid實現相冊同步與展示的方案探討

背景:Unraid作為一個NAS系統,能夠實現基本的NAS文件管理功能,但是不提供額外的功能如影音、同步、辦公、和內網穿透等,這些在其他的NAS產品如群暉、綠聯、威聯通等都是提供支持的。然而unraid也有其他方案,即通過特別方…

常見的網絡攻擊手段

IP 欺騙 IP 是什么? 在網絡中,所有的設備都會分配一個地址。這個地址就仿佛小藍的家地址「多少號多少室」,這個號就是分配給整個子網的,「室」對應的號碼即分配給子網中計算機的,這就是網絡中的地址。「號」對應的號碼為網絡號…

積分形式的輻射傳輸方程

The Equation of Transfer in Integral Form Let L L L be the streaming-collision operator, and S S S is scattering operator, we have L I Ω ? ? I ( r , Ω ) σ ( r , Ω ) I ( r , Ω ) LI\Omega\cdot\nabla I(r,\Omega)\sigma(r,\Omega)I(r,\Omega) LIΩ??…

JS中reduce方法

JavaScript 中的 reduce 方法是一個非常強大的數組方法,它允許你對數組中的所有元素執行一個“reducer”函數,從而將數組“減少”到一個單一的值。以下是 reduce 方法的詳細介紹: 語法 array.reduce(function(accumulator, currentValue, c…

印閃網絡:阿里云數據庫MongoDB版助力金融科技出海企業降本增效

客戶背景 上海印閃網絡科技有限公司,于2017年1月成立,投資方包括紅杉資本等多家國際知名風投公司。公司業務聚焦東南亞普惠金融,常年穩居行業頭部。創始團隊來自騰訊,中國團隊主要由運營、風控及產研人員組成,核心成員…

【后端面試總結】HTTPS工作原理詳解

引言 在現代網絡通信中,數據的安全性至關重要。HTTP(Hypertext Transfer Protocol)作為互聯網上傳輸數據的協議,雖然應用廣泛,但其數據以明文形式傳輸,存在被竊取和篡改的風險。為此,HTTPS&…

51c嵌入式~單片機~合集2

我自己的原文哦~ https://blog.51cto.com/whaosoft/12362395 一、不同的電平信號的MCU怎么通信? 下面這個“電平轉換”電路,理解后令人心情愉快。電路設計其實也可以很有趣。 先說一說這個電路的用途:當兩個MCU在不同的工作電壓下工作&a…