ARM筆記-ARM指令集

第三章 ARM指令集

3.1 ARM指令集簡介

  • ARM微處理器的ARM指令集 ,所有的指令長度都是32位 ,并且大多數指令都在一個單獨指令周期內執行
    • 主要特點:
      • 指令是條件執行的
      • ARM微處理器的指令集是加載/存儲型的
      • 在多寄存器操作指令中一次最多可以完成 16個寄存器的數據傳送

3.1.1 ARM指令格式

一、 ARM指令格式

<opcode>{<Condition>}{S} {<Rd>}{,<Rn>}{,<Operand2>}

  • 格式中< >的內容必不可少,{ }中的內容可省略。

    • <opcode>表示操作碼,如ADD表示算術加法
    • {<cond>}表示指令執行的條件域,如EQ、NE等
    • {S}決定指令的執行結果是否影響CPSR的值,使用該后綴則指令執行的結將果影響CPSR的值,否則不影響。
    • <Rd>表示目標或源寄存器
    • <Rn>表示第一個操作數,為寄存器
    • <Operand2>表示第二個操作數,可以是立即數、寄存器和寄存器移位操作數
  • 除了<opcode>其余域都可以選擇使用。

  • 舉例

    例如: 指令ADDEQS R0,R1,#8;操作碼為ADD,條件域cond為EQ,S表示該指令的執行影響CPSR寄存器的值,目的寄存器Rd為R0,第一個操作數寄存器Rn為R1,第二個操作數OP2為立即數#8。執行結果:R0 = R1+ 8
    
二、 指令的機器碼
  • 從形式上看,ARM指令在機器中的表示格式是用32位的二進制數表示。
    • 如ARM中有一條指令為:
      • ADDEQS R0, R1, #8
      • 其二進制代碼形式為
31~2827~2524~212019~1615~1211~0
00000010100100010000000000001000
condopcodesRnRdOp2
  • ARM指令一般可以分為5個域

    • 第1個域–4位
      • 4位[31:28]的條件碼域,4位條件碼共有16種組合
    • 第2個域–8位
      • 指令代碼域[27:20],除了指令編碼外,還包含幾個很重要的指令特征和可選后綴的編碼
    • 第3個域–4位
      • 第1個操作數寄存器Rn,是4位[19:16],為R0~R15共16個寄存器編碼
    • 第4個域–4位
      • 目標或源寄存器Rd,是4位[15:12],為R0~R15共16個寄存器編碼
    • 第5個域–12位
      • 第二個操作數[11:0]
三、指令的可選后綴
  1. S后綴

    • 指令中使用S后綴時,指令執行后,CPSR的條件標志位將被刷新
    • 不使用S后綴時,指令執行后,CPSR的條件標志將不會發生變化。
    例:假設R0=0x1,R3=0x3,指令執行之前CPSR部分標志位為 nZcv,分別執行如下指令CPSR的值有何變化?SUB R1,R0,R3SUBS R1,R0,R3
    
    • 分析:
      • 執行第1條指令對于標志寄存器的值沒有任何影響,因此CPSR的值不變。
      • 執行第2條指令后CPSR=Nzcv。
  2. !后綴

    • 如果指令地址表達式中不含!后綴,則基址寄存器中的地址值不會發生變化。

    • 指令中的地址表達式中含有!后綴時,指令執行后,基址寄存器中的地址值將發生變化,變化的結果如下:

      • 基址寄存器中的值(指令執行后)=指令執行前的值+地址偏移量
      例:分別執行下面兩條指令有何區別?LDR R3,[R0,#4] LDR R3,[R0,#4]!
      
      • 分析:
        • 第1條指令沒有!后綴,指令的結果是把R0加4作為地址指針,把這個指針所指向的地址單元所存儲的數據讀入R3,R0的值不變
        • 第2條指令除了實現以上操作外,還把R0+4的結果送到R0中
    • 使用!后綴需要注意如下事項:

      • !后綴必須緊跟在地址表達式后面,而地址表達式要有明確的地址偏移量
      • !后綴不能用于R15(PC)的后面
      • 當用在單個地址寄存器后面時,必須確信這個寄存器有隱性的偏移量
        • 例如“STMIA R7!, {R0 – R3}”
          • 此時地址基址寄存器R7的隱性偏移量是16字節(因為連續壓棧了4個寄存器的值,每一個寄存器的值為4字節長度,即一個字)
          • 如果R7的初始值為 0X40000000,則該語句結束后為0X40000010
  3. B后綴

    • 指令所涉及的數據是一個字節,不是一個字或半字
    LDR R4,[R0]R4=[R0],指令傳送一個字
    LDRB R4,[R0]R4=[R0],指令傳送一個字節
    LDREQB R4,[R0]如果相等則執行,R4=[R0],指令傳送一個字節

3.1.2 ARM指令的條件碼

  • 當處理器工作在 ARM狀態時,幾乎所有的指令均能根據CPSR中的條件標志位的狀態和指令的條件域有條件地執行。

    • 當指令的執行條件滿足時,指令被執行,否則指令被忽略
    • 條件后綴只影響指令是否執行,不影響指令的內容
  • ARM指令的條件碼助記符如下表所示:(不用記)

    條件碼條件碼助記符CPSR中條件標志位值含義
    0000EQZ=1相等
    0001NEZ=0不相等
    0010CS/HSC=1無符號數大于或等于
    0011CC/LOC=0無符號數小于
    0100MIN=1負數
    0101PLN=0正數或零
    0110VSV=1溢出
    0111VCV=0未溢出
    1000HIC=1且Z=0無符號數大于
    1001LSC=0或Z=1無符號數小于或等于
    1010GEN=V帶符號數大于或等于
    1011LTN!=V帶符號數小于
    1100GTZ=0且N=V帶符號數大于
    1101LEZ=1或N!=V帶符號數小于或等于
    1110AL無條件執行
    1111NVARMV3之前從不執行(不要使用)
    • 條件后綴和S后綴的關系
      • 如果既有條件后綴又有S后綴,則書寫時S排在后面
        • 如:ADDEQS R1,R0,R2
          • 該指令在Z=1時執行,將R0+R2的值放入R1,同時刷新條件標志位
      • 條件后綴是要測試條件標志位,而S后綴是要刷新條件標志位
      • 條件后綴要測試的是執行前的標志位,而S后綴是依據指令的結果改變條件標志

3.1.3 ARM指令分類

  • ARM 指令可以分為:分支指令、數據處理指令、存儲訪問指令、協處理器指令、雜項指令五類。
  1. 分支指令:分支指令用于控制程序的執行流程實現ARM代碼與Thumb代碼之間進行切換
  2. 數據處理指令:數據處理指令在通用寄存器上執行計算
    • 主要分為3種:算術/邏輯指令、比較指令和乘法指令。
  3. 存儲訪問指令:用于 加載/存儲 存放于MCU片外存儲系統中的數據
    • 加載指令用于從內存中讀取數據放入寄存器中
    • 存儲指令用于將寄存器中的數據保存到內存中
  4. 協處理器指令:ARM協處理器指令用于控制外部的協處理器。包括:
    • 數據處理指令:啟動一個協處理器專用的內部操作。
    • 數據轉移指令:使數據在協處理器和存儲器之間進行轉移。
    • 寄存器轉移指令:協處理器值轉移到ARM寄存器或ARM寄存器的值轉移到協處理器。
  5. 雜項指令:包括狀態寄存器轉移指令異常中斷產生指令
    • 狀態寄存器轉移指令
      • 將CPSR或SPSR的內容轉移到一個通用寄存器,或者反過來將通用寄存器的內容寫入CPSR或SPSR寄存器
    • ARM有兩條異常中斷產生指令,分別為 軟中斷指令SWI斷點中斷指令BKPT

3.2 指令尋址方式

3.2.1 立即數尋址

  • 立即數尋址也叫立即尋址,操作數本身就在指令中給出取出指令也就取到了操作數。這個操作數被稱為立即數,對應的尋址方式也就叫做立即數尋址。

    • 立即數要求以“#”為前綴

      • 對于以十六進制表示的立即數,還要求在“#”后加上**“0x”或“&”**
      • 對于以二進制表示的立即數,要求在“#”后加上**“0b”**
      • 對于以十進制表示的立即數,要求在“#”后加上**“0d”或缺省**
    • 舉例

      • MOV R0, #15 ; R0←#15

        • 此指令是將立即數15傳送到R0中,該指令的機器編碼為E3A0000FH(H表示16進制)

        • 由指令編碼中0x00F即可得到一個32位的立即0x0000000FH,這個數再送入R0

      • Q:如何在指令編碼中表達32位立即數?

      • A:

3.2.2 寄存器尋址

  • 寄存器尋址就是利用寄存器中的數值作為操作數,這種尋址方式是各類微處理器經常采用的一種方式,也是一種執行效率較高的尋址方式
    • 例:
      • MOV R1,R2 ;R1←R2
      • ADD R0,R1,R2 ;R0←R1+R2

3.2.3 寄存器移位尋址

  • 第二操作數為寄存器型時,在執行寄存器尋址操作時,也可以對第二操作數寄存器進行移位,此時第二操作數形式為:
    • ADD Rd, Rn, Rm,{<shift>}
      • 其中:
        • Rm:稱為第二操作數寄存器
        • <shift>:用來指定移位類型和移位位數,有兩種形式:
          • 5位立即數(其值小于32)
          • 寄存器(用Rs表示)(其值小于32)
  • 在指令執行時,將寄存器移位后的內容,作為第二操作數參與運算。
    • 例如指令:
      • ADD R3,R2,R1,LSR #2 ;R3←R2+(R1右移2位)
      • ADD R3,R2,R1,LSR R0 ;R3←R2+(R1右移R0位)
  • 第二操作數的移位方式
    • LSL 邏輯左移 :
      • 邏輯左移,空出的最低有效位用0填充。
      • SUB R3,R2,R1,LSL #2 ;R3←R2-(R1左移2位)
    • LSR 邏輯右移 :
      • 邏輯右移,空出的最高有效位用0填充。
      • SUB R3,R2,R1,LSR R0 ;R3←R2-(R1右移R0位)
    • ASL 算術左移 :
      • 算術左移,由于左移空出的有效位用0填充,因此它與LSL同義。
    • ASR 算術右移 :
      • 算術右移 (Arithmetic Shift Right) 。算術移位的對象是帶符號數,移位過程中必須保持操作數的符號不變。如果源操作數是正數,空出的最高有效位用0填充,如果是負數用1填充
    • ROR 循環右移
      • 循環右移(Rotate Right),移出的字的最低有效位依次填入空出的最高有效位
    • RRX 帶擴展的循環右移
      • 帶進位位的循環右移(Rotate Right Extended) 。將寄存器的內容循環右移1位,空位用原來C標志位填充
      • SUB R3,R2,R1,RRX ;R3←R2-(R1帶進位位循環右移1位)
  • 第二操作數的移位位數
    • 移位位數可以用立即數方式或者寄存器方式給出其值均小于32,應為0—31
    • 如下所示:
      • ADD R3,R2,R1,LSR #2 ;R3=R2+(R1右移2位)
      • ADD R3,R2,R1,LSR R4 ;R3=R2+(R1右移R4位)
      • 寄存器R1的內容分別邏輯右移2位、R4位,再與寄存器R2的內容相加,結果放入R3中。

3.2.4 寄存器間接尋址

  • 寄存器間接尋址就是以寄存器中的值作為操作數的地址,而操作數本身存放在存儲器中
    • 例:LDR R0,[R4] ;R0←[R4]

3.2.5 基址變址尋址

  1. 變址尋址

    • 也叫基址變址尋址:將基址寄存器的內容與指令中給出的地址偏移量相加,得到操作數所在的存儲器的有效地址。

    • 變址尋址方式常用于訪問某基地址附近的地址單元。(4K范圍的偏移)

      • 例如: LDR R0,[R1,#4] ;R0←mem32[R1+4]
  2. 加偏移地址的方式

    • 前變址模式(不修改基址寄存器)

      • 基址+偏址,生成操作數地址,再做指令指定的操作。也叫前索引偏移

    • 自動變址模式(修改基址寄存器):

      • 基址+偏址,生成操作數地址,做指令指定的操作
      • 然后自動修改基址寄存器
        • 例如:LDR R0,[R1,#4]!
          • 先 R0←mem32 [R1+4]
          • 然后 R1←R1+4
          • ! 表示更新基址寄存器。
    • 后變址模式(修改基址寄存器):

      • 基址寄存器不加偏移作為操作數地址

      • 完成指令操作后,用(基址+偏移)的值修改基址寄存器

      • 先用基地址傳數,然后修改基地址(基址+偏移),也叫后索引偏移

  3. 偏移地址形式

    • 可以是一個立即數,也可以是另一個寄存器,并且還可以是寄存器移位操作

      • 常用的是立即數偏移的形式。
    • 如下所示:

      • LDR R2,[R3,#0X0C] ;R2< —[R3+0X0C]

      • STR R1,[R0,#-0x4]!

        • ;R1 —>mem32[R0-4],
        • ;R0=R0-4
      • LDR r0,[r1,r2] ;r0<—mem32[r1+r2]

      • LDR r0,[r1,r2,LSL #2] ;r0<—mem32[r1+r2*4]]

3.2.6 多寄存器尋址

  • 采用多寄存器尋址方式,一條指令可以完成多個寄存器值的傳送
  • 這種尋址方式是多寄存器傳送指令 LDM/STM 的尋址方式,這種尋址方式中用一條指令最多可傳送16個通用寄存器的值
  • 連續的寄存器間用 - 連接,否則用 , 分隔。
    • LDMIA R0!,{R1-R4} ;R1←**[R0]、R2←[R0+4]、R3←[R0+8]、R4←[R0+12]**
  • 注意:
    • 對于所有LDM/STM指令而言,寄存器序號低的,在低地址單元序號大的在高地址單元
    • 與書寫順序無關!

?

  • 4種尋址操作
    • LDMIA/STMIA Increment After(先傳送,后地址加4)
    • LDMIB/STMIB Increment Before(先地址加4 ,后傳送)
    • LDMDA/STMDA Decrement After(先傳送,后地址減4)
    • LDMDB/STMDB Decrement Before (先地址減4,后傳送)

3.2.7 堆棧尋址

  • 堆棧是一種數據結構,按后進先出(Last In First Out, LIFO)的方式工作,使用一個稱作堆棧指針的專用寄存器指示當前的操作位置,堆棧指針總是指向棧頂。

  • 堆棧可分為兩種增長方式

    • 向上生長:向高地址方向生長,稱為遞增堆棧
    • 向下生長:向低地址方向生長,稱為遞減堆棧
  • 根據堆棧指針指向的數據位置的不同,可分為:

    • 滿堆棧:堆棧指針指向最后壓入堆棧的有效數據項,稱為滿堆棧;
    • 空堆棧:堆棧指針指向下一個待壓入數據的空位置,稱為空堆棧。
  • 這樣就有4種類型的堆棧表示遞增和遞減的滿和空堆棧的各種組合。

    • 四種類型的堆棧工作方式
      • 滿遞增堆棧FA(Full Ascending):堆棧指針指向最后壓入的數據,且由低地址向高地址生長。
      • 滿遞減堆棧FD(Full Descending) :堆棧指針指向最后壓入的數據,且由高地址向低地址生長。
      • 空遞增堆棧EA(Empty Ascending):堆棧指針指向下一個將要放入數據的空位置,且由低地址向高地址生長。
      • 空遞減堆棧ED(Empty Descending):堆棧指針指向下一個將要放入數據的空位置,且由高地址向低地址生長。
    • 也就是說上面的遞增遞減都指的是堆棧生長方向,即入棧時遞增還是遞減

3.2.8 相對尋址

  • 與基址變址尋址方式相類似,相對尋址以程序計數器PC的當前值為基地址,指令中的地址標號作為偏移量,將兩者相加之后得到操作數的有效地址。

3.3 ARM指令集

3.3.1 分支指令

  • 在ARM中有兩種方式可以實現程序的跳轉:

    • 一種是使用分支轉移指令直接跳轉
    • 另一種則是直接向PC寄存器賦值來實現跳轉
  • ARM的分支轉移指令,可以從當前指令向前或向后的32MB的地址空間跳轉,根據完成的功能它可以分為以下4種

一、B & BL
  • B 指令與 BL 指令的編碼格式如下:

    • 從編碼中看到L控制了PC與LR寄存器之間的開關
      • 當L=0 時,該開關斷開,指令為B指令;
      • 當L=1時,該開關接通,指令為BL指令。
    • Signed_immed_24表示24位有符號的立即數(偏移量
  • B 和 BL 指令的助記符格式為:

    • B{<cond>} <target>和BL{<cond>} <target>
      • cond表示指令執行條件
      • target表示跳轉地址
      • 功能:跳轉到指定地址執行,地址范圍限制在當前PC寄存器所指向的指令地址的±32MB范圍
    • 跳轉指令也叫程序轉移指令
    • 寫匯編程序時,可以跳轉到一個絕對地址,如:
      • B 0x1234 (注: B #0x1234是錯誤的
      • 編譯器會把該絕對地址轉換為相對地址放入指令中
  • signed_immed_24 間接提供目標地址真正的目標地址是由處理器根據這個有符號數和當前的PC值計算出來的

    • 具體計算為:
      • 先將 signed_immed_24 左移兩位(即具有26位的偏移量),并擴展為32位有符號數
      • 然后再將這32位有符號數與 PC 的當前值相加,得到實際的跳轉地址。
      • 因此B 和 BL 指令轉移的偏移量為 26 位,即轉移的跨度為前后 32MB 地址空間
  • B和BL的區別:

    • BL在跳轉之前會把BL指令的下一條指令地址(斷點地址)保存到連接寄存器 LR(R14),因此程序在必要的時候可以通過將 LR 的內容加載到 PC 中,使程序返回到跳轉點。
    • BL 指令經常被用來調用一個子程序。
二、BX
  • BX 指令的格式:

    • BX{<cond>} Rm
    • cond表示指令執行條件
    • Rm寄存器,值是絕對地址值,不是偏移量,在指令執行后,Rm中的地址值與#0XFFFF FFFE 進行 “與” 運算,再被復制到程序計數器PC。
      • Rm[0]為1時,強制程序從ARM指令狀態跳轉到Thumb指令狀態。
      • Rm[0]為0時,強制程序從Thumb 指令狀態跳轉到ARM指令狀態。
    • 功能: 跳轉到指令中所指定的目標地址,并實現狀態切換。(T<-Rm[0]
  • 指令編碼格式

三、BLX
  • BLX 指令的格式有兩種:
    • BLX <target>BLX{<cond>} Rm
      • 以target方式提供目標地址的 BLX 指令的功能是:
        • 把程序跳轉到指令中所指定的目標地址繼續執行,并同時將處理器的工作狀態從ARM狀態切換到Thumb狀態,并將下一條的地址保存到寄存器 LR 中。
      • 以 Rm 方式提供目標地址的 BLX 指令,除了跳轉和下一條的地址保存到LR之外,也可進行狀態切換,但其切換的依據是Rm最低位的值
        • 如果值為0 ,則目標地址處應為 ARM指令
        • 如果值為1 ,則目標地址處應為 Thumb 指令
四、長跳轉
  • 另一種實現指令跳轉的方式是通過直接向 PC 寄存器中寫入目標地址值,實現在4GB 地址空間中任意跳轉,這種跳轉又稱為長跳轉
  • 如果在長跳轉指令之前使用“MOV LR,PC” 等指令,可以保存將來返回的地址值,也就實現了在 4GB 的地址空間中的子程序調用。

3.3.2 數據處理指令

一、數據處理指令概述
  1. ARM數據處理指令的功能

    • 主要完成寄存器中數據的算術和邏輯運算操作。
  2. ARM數據處理指令的特點

    • 操作數來源:所有的操作數要么來自寄存器,要么來自立即數,不會來自存儲器
    • 操作結果:如果有結果,則結果一定是為32位寬、或64位寬(長乘法指令),并且放在一個或兩個寄存器中,不會寫入存儲器
    • 有第二個操作數(除了乘法指令)Operand2 :切記其三種形式:立即數、寄存器、寄存器移位。
    • 乘法指令的操作數:全部是寄存器。
  3. ARM數據處理指令分類

    • 22條可分為5類:
      • 算術運算指令:ADD ADC SUB SBC RSB RSC MUL MLA UMULL UMLAL SMULL SMLAL
      • 邏輯運算指令:AND ORR EOR BIC
      • 數據傳送指令:MOV MVN
      • 比較指令:CMP CMN
      • 測試指令:TST TEQ
    • 上述指令只能對寄存器操作,不能針對存儲器
  4. 數據處理指令對程序狀態寄存器CPSR的影響

    • 指令中可以選擇s后綴,以影響狀態標志

      • 但是比較指令(CMP和CMN)和測試指令(TST和TEQ)不需要后綴S,它們總會直接影響CPSR中的狀態標志
    • 關于恢復CPSR原值問題:

      • 如果指令帶有S后綴(除了比較指令以外),同時又以PC為目標寄存器進行操作:

        • 在異常模式下:則操作的同時從SPSR恢復CPSR

        • 比如:

          movs pc, #0xff	/* cpsr = spsr; pc = 0xff */
          adds pc, r1, #0xff00/* cpsr = spsr; pc = r1 + 0xff00 */
          ands pc, r1, r2	/* cpsr = spsr; pc = r1 & r2; */
          
          • 在user或者system模式:會產生不可預料的結果,因為在這兩種模式下沒有SPSR
  5. 數據處理指令的詳細列表(未含6條乘法指令)

    • 指令編碼格式

      • opcode為數據處理指令操作碼
      • I用于區別立即數(I為1)或寄存器移位(I為0)
      • S用于設置標志位
      • Rn為第一操作數寄存器,Rd為目標寄存器
      • operand2為第二個操作數,若指令不需要全部的可用操作數時(如MOV指令的Rn),不用的寄存器域應設置為0(由編譯器自動完成)
      • 對于比較指令,b20位固定為1。
二、算術運算指令
  1. 加減運算指令

    • ADD——加法運算指令

      • 指令格式:ADD{cond}{S} Rd,Rn,operand2

      • ADD指令把第1源操作數寄存器Rn第2源操作數operand2相加后,將結果存放到目的寄存器 Rd

      • 執行流程(后面的指令,流程類似便不再列舉了)

        • 舉例:
          • ADD R0,R1,R2 ;R0←(R1)+(R2)
          • ADD R0,R1,#255 ;R0 ←(R1)+ 255
          • ADD R0,R2,R3,LSL#1 ;R0 ←(R2) +(R3<<1)
      • 受影響的CPSR標志位取值
        N寄存器Rd[31]被復制到N
        Z如果Rd為0,則Z=1,否則Z=0
        C運算結果有進位C=1,否則C=0
        V運算結果有溢出V=1,否則V=0
    • ADC——帶進位加法指令

      • 指令格式:ADC{cond}{S} Rd,Rn,operand2
      • ADC指令將operand2的數據與Rn的值相加,再加上CPSR中的C條件標志位,結果保存到Rd寄存器。
      • 標志位只修改 N、Z、C、V這4個標志位
      • ADC通常用來實現字長大于32位的加法運算。
    • SUB——減法運算指令

      • 指令格式:SUB{cond}{S} Rd,Rn,operand2

      • SUB指令用寄存器Rn減去operand2,結果保存到Rd中

      • 受影響的CPSR標志位取值
        N寄存器Rd[31]被復制到N
        Z如果Rd為0則Z=1,否則Z=0
        C運算結果有借位則C=0,否則C=1
        V運算結果有溢出則V=1,否則V=0
    • SBC——帶進位減法指令

      • 指令格式:SBC{cond}{S} Rd,Rn,operand2
      • SBC指令用寄存器Rn減去operand2,再減去CPSR中的C條件標志位的反碼,結果保存到Rd中。
      • 標志位的修改同 SUB。
      • 該指令主要用于字長大于 32 位的數據的減法運算。
    • RSB——逆(反)向減法指令

      • 指令格式:RSB{cond}{S} Rd,Rn,operand2
      • RSB指令用operand2減去寄存器Rn,結果保存到Rd中。
    • RSC——帶進位反向減法指令

      • 指令格式:RSC{cond}{S} Rd,Rn,operand2
      • RSC 指令用寄存器operand2減去Rn,再減去CPSR中的C條件標志位的反碼,結果保存到Rd中。
  2. 乘法指令

    • ARM有兩類乘法指令:

      • 32位的乘法指令,即乘法操作的結果為32位

      • 64位的乘法指令,即乘法操作的結果為64位

    • MUL——32位乘法指令

      • 指令格式:MUL{cond}{S} Rd,Rm,Rs

      • MUL指令將Rm和Rs中的值相乘,結果的低32位保存到Rd中(Rd ≠ Rm

      • 受影響的CPSR標志位取值
        N寄存器Rd[31]被復制到N
        Z如果Rd為0則Z=1,否則Z=0
    • MLA——32位乘加指令

      • 格式:MLA{cond}{S} Rd,Rm,Rs,Rn
      • 指令將Rm和Rs中的值相乘,再將乘積加上第3個操作數,結果的低32位保存到Rd中( Rd ≠ Rm )
      • 標志位的修改同 MUL
    • UMULL——64位無符號乘法指令

      • 指令格式:UMULL{cond}{S} RdLo,RdHi,Rm,Rs ; RdHi, RdLo← Rm*Rs

      • UMULL指令將Rm和Rs中的值作無符號數相乘,結果的低32位保存到RdLo中,高32位保存到RdHi中

      • 受影響的CPSR標志位取值
        N寄存器**RdHi[31]**被復制到N
        Z如果RdHi且Rdlo為0,則Z=1,否則Z=0
    • **UMLAL——64位無符號乘加指令 **

      • 指令格式:UMLAL{cond}{S} RdLo,RdHi,Rm,Rs ;RdHi, RdLo← Rm*Rs+ RdHi, RdLo
      • UMLAL指令將Rm和Rs中的值作無符號數相乘,64位乘積與RdHi、RdLo相加,結果的低32位保存到RdLo中,而高32位保存到RdHi中
      • 標志的修改同 UMULL
    • SMLAL—64位有符號乘加指令

      • 指令格式:SMLAL{cond}{S} RdLo,RdHi,Rm,Rs ; RdHi, RdLo← Rm*Rs+ RdHi, RdLo
      • SMLAL指令將Rm和Rs中的值作有符號數相乘64位乘積與RdHi、RdLo相加,結果的低32位保存到RdLo中,高32位保存到RdHi中
      • 標志的修改同 SMULL。
    • 乘法指令的特點

      • 不支持第2操作數為立即數
      • 結果寄存器不能與第一源寄存器相同
      • Rd、RdHi、RdLo不能與Rm為同一寄存器。
      • RdHi和RdLo不能為同一寄存器。
      • 避免將R15定義為任一操作數或結果寄存器
    • 乘法指令對標志位的影響

      • 對N標志位:
        • 若結果是32位指令形式,Rd的第31位是標志位N
        • 對于產生長結果的指令形式,RdHi的第31位是標志位N
      • 對Z標志位:如果Rd或RdHi、RdLo為0,則標志位Z置位
      • 對V標志位:乘法指令不影響V標志位
      • 對C標志位: ARM v5及以上的版本不影響C標志位; ARM v5以前的版本,C標志位數值不確定
    • 指令編碼格式

      • opcode為乘法指令操作碼
      • S為設置標志位
      • Rm為被乘數寄存器,Rs為乘數的寄存器
      • Rn/RdLo用于MLA指令相加的寄存器或64位乘法指令的目標寄存器(低32位)。
      • Rd/RdHi用于目標寄存器或64位乘法指令的目標寄存器(高32位)。
      • 若指令不需要全部的可用操作數時(如MUL指令的Rn),不用的寄存器域應設置為0(由編譯器自動完成)。
三、邏輯運算指令(按位邏輯操作指令)
  • AND——邏輯“與”操作指令

    • 指令格式:AND{cond}{S} Rd,Rn,operand2

    • AND指令將operand2的值與寄存器Rn的值**按位邏輯“與”**操作,結果保存到Rd中。

    • 執行流程

    • 受影響的CPSR標志位取值
      N寄存器Rd[31]被復制到N
      Z如果Rd為0則Z=1,否則Z=0
      C不影響C標志位

      AND指令可用于提取寄存器中某些位的值,也可以用于把指定位清0

  • ORR——邏輯“或”操作指令

    • 指令格式: ORR{cond}{S} Rd,Rn,operand2
    • ORR指令將**operand2的值與寄存器Rn的值按位邏輯“或”**操作,結果保存到Rd中。
    • ORR指令用于將寄存器中某些位的值設置成1
    • 標志位的影響同AND。
  • EOR——邏輯“異或”操作指令

    • 指令格式:EOR{cond}{S} Rd,Rn,operand2
    • EOR指令將**operand2的值與寄存器Rn的值按位邏輯“異或”**操作,結果保存到Rd中。
    • EOR指令可用于將寄存器中某些位的值取反
      • 與0異或,該位值不變
      • 與1異或,該位值被求反
    • 標志位的影響同AND
  • BIC——位清除指令

    • 指令格式:BIC{cond}{S} Rd,Rn,operand2
    • BIC指令將寄存器Rn的值與operand2的值的反碼按位邏輯**“與”**操作,結果保存到Rd中。
    • BIC指令可用于將寄存器中某些位的值清除為0
      • 將某一位 與1 做BIC操作,該位值被清除為0 ;
      • 將某一位 與0 做BIC操作,該位值不變。
四、數據傳送指令
  1. MOV——數據傳送指令

    • 指令格式:MOV{cond}{S} Rd,operand2

    • MOV指令將operand2傳送到目標寄存器Rd中。

    • 受影響的CPSR標志位取值
      N寄存器Rd[31]被復制到N
      Z如果Rd為0,則Z=1,否則Z=0
      CC=0
    • 功能總結

      • 寄存器之間傳送。
      • 立即數傳送到寄存器中。(8位立即數位圖)
      • 實現單純的移位操作。MOV Rd,Rd,LSL,#3
      • 實現子程序調用、從子程序中返回。當PC寄存器作為目標寄存器時可以實現程序跳轉。
      • 實現異常模式的返回,并把當前處理器模式的SPSR寄存器內容復制到CPSR中
        • 例:MOVS PC,LR ;PC←LR,異常模式下返回,且CPSR←SPSR
  2. MVN——數據求反傳送指令

    • 指令格式:MVN{cond}{S} Rd,operand2
    • MVN指令將operand2按位取反后傳送到目標寄存器Rd中。
五、比較指令
  1. CMP——比較指令

    • 指令格式:CMP{cond} Rn,operand2

    • CMP指令將寄存器Rn的值減去operand2的值,但不存儲運算結果只根據操作的結果更新CPSR中的相應條件標志位,以便后面的指令根據相應的條件標志來判斷是否執行。

    • 受影響的CPSR標志位取值
      N運算結果的第31位被復制到N
      Z運算結果為0則Z=1,否則Z=0
      C運算結果有借位則C=0,否則C=1
      V運算結果有溢出則V=1,否則V=0
    • 比較類指令本身帶有更新 CPSR的功能,故在該指令中不能使用后綴 S

  2. CMN——負數比較指令

    • 指令格式:CMN{cond} Rn,operand2
    • CMN指令將寄存器Rn的值減去operand2的負數(即加上operand2的值),但不存儲運算結果,只根據操作的結果更新CPSR中的相應條件標志位,以便后面的指令根據相應的條件標志來判斷是否執行。
六、測試指令
  1. TST——位測試指令
    • 指令格式:TST{cond} Rn,operand2
    • TST指令將寄存器Rn的值與operand2的值按位邏輯“與”操作,但不存儲運算結果,只根據操作的結果更新CPSR中的相應條件標志位
    • 該指令一般用來檢測是否設置了特定的位
  2. TEQ——測試相等指令
    • 指令格式:TEQ{cond} Rn,operand2
    • TEQ指令將寄存器Rn的值與operand2的值**按位邏輯“異或”**操作,但不存儲運算結果,只根據操作的結果更新CPSR中的相應條件標志位,以便后面的指令根據相應的條件標志來判斷是否執行。
      • 例子:
        • TEQ R0,R1
        • ;比較R0與R1是否相等
        • ;(不影響V位和C位)

3.3.3 存儲器訪問指令

  • ARM微處理器用加載/存儲指令訪問存儲器,實現在寄存器和存儲器之間傳送數據。
  • 由于ARM處理器對外設寄存器、I/O映射空間與存儲器統一編址,因此,對外圍設備的I/O操作也用此類指令
  • 基本的加載/存儲指令僅有5條,分為3種:
    • LDR和STR,單寄存器加載/存儲指令
    • LDM和STM,多寄存器加載/存儲指令
    • SWP,寄存器和存儲器數據交換指令
一、 單寄存器的存取指令
  • 單寄存器加載/存儲指令是ARM在寄存器和存儲器間傳送單個字節和字的最靈活方式。
  • 根據傳送數據的類型不同,單個寄存器存取指令又可以分為以下兩類:
    • 單字和無符號字節的加載/存儲指令
    • 半字和有符號字節的加載/存儲指令
  1. 單字和無符號字節的加載/存儲指令

    • LDR:指令從內存中取32位字或8位無符號字節數據放入寄存器

      • 內存到寄存器
    • STR:指令將寄存器中的32位字或8位無符號字節數據保存到存儲器中。

      • 寄存器到內存
    • 注意:無符號字節加載時,用0將8位的操作數擴展到32位

    • 指令格式

      • LDR{cond}{T} Rd,<地址> ;加載指定地址上的字數據,放入Rd中。
      • STR{cond}{T} Rd,<地址> ;存儲Rd中字數據,到指定地址的存儲單元。
      • LDR{cond}B{T} Rd,<地址> ;加載字節數據到Rd低8位數據位中,高24位為0
      • STR{cond}B{T} Rd,<地址> ;存儲Rd中字節數據, Rd中最低字節為傳送數據
      • T后綴
        • T為可選后綴,若指令有T,存儲系統將訪問看成是處理器在用戶模式下。
        • 用于存儲器保護。
        • 不能與后變址模式、自動變址模式一起使用(即不能改變基址寄存器值)。
        • T在用戶模式下無效。
    • 操作數尋址方式

      • LDR/STR指令為基址變址尋址(或寄存器間接尋址),由兩部分組成:

        • 基地址部分:為一個基址寄存器,可以為任一個通用寄存器

        • 偏移地址部分:這一部分非常靈活,實際就類似第二個操作數,可以有以下3種格式:

          • 立即數:12位立即數是一個無符號的數值。這個數據可以加到基址寄存器,也可以從基址寄存器中減去這個數值。

            • 指令舉例如下:

              LDR    R1,[R0,#0x10]      ;將R0+0x10地址處的數據讀出,			;保存到R1中(R0的值不變)       
              LDR    R1,[R0,# -0x10]       			;將R0-0x10地址處的數據讀出,			;保存到R1中(R0的值不變)
              
          • 寄存器:寄存器中的數值(無符號數)可以加到基址寄存器,也可以從基址寄存器中減去這個數值。

            • 指令舉例如下:

              LDR    R1,[R0,R2] ;將R0+R2地址處的數據讀出,保存到R1中
              LDR    R1,[R0,-R2] ;將R0-R2地址處的數據讀出,保存到R1中
              
          • 寄存器及移位常數:寄存器移位后的值(無符號數)可以加到基址寄存器,也可以從基址寄存器中減去這個數值。

            • 指令舉例如下:

              LDR    R1,[R0,R2,LSL #2];將R0+R2×4地址處的數據讀出,;保存到R1中(R0、R2的值不變)
              LDR    R1,[R0,-R2,LSL #2];將R0-R2×4地址處的數據讀出,;保存到R1中(R0、R2的值不變)
              
              • 注意:移位位數只能是5位的立即數,不能使用寄存器指定移位位數
    • 指令編碼格式

  2. 半字和有符號字節的加載/存儲指令

    • 這類LDR/STR指令可實現半字(有符號和無符號)、有符號字節數據的傳送。

    • 特點:

      • 偏移量格式、尋址方式與加載/存儲字和無符號字節指令基本相同
      • 立即數偏移量限定在8位
      • 寄存器偏移量不可經過移位得到。
    • 指令格式

      • LDR {cond}SB Rd,<地址> ;加載指定地址上有符號字節到Rd中,高24位用符號位擴展
      • LDR {cond}SH Rd,<地址> ;加載指定地址上的有符號半字到Rd中,高16位用符號位擴展
      • LDR {cond}H Rd,<地址> ;加載無符號半字數據到Rd的低16位,高16位清零
      • STR{cond}H Rd,<地址> ;存儲Rd中的低16位半字數據
    • 兩點說明:

      • 符號位
        • 有符號字節或有符號半字的加載,用**“符號位”擴展到32位**
        • 無符號半字傳送是用0擴展到32位
      • 地址對齊
        • 對半字傳送的地址必須為偶數。非半字對齊的半字加載將使Rd內容不可靠
        • 非半字對齊的半字存儲將使指定地址的2字節存儲內容不可靠。
    • 指令編碼格式

  • 看PPT的例子P127-130
二、多寄存器的存取指令
  • LDM和STM指令可以實現在一組寄存器一塊連續的內存單元之間存/取數據。

    • LDM為加載多個寄存器(內存到寄存器
    • STM為存儲多個寄存器(**寄存器到內存)
  • 這兩條指令,允許傳送16個寄存器R0—R15的任何子集或所有寄存器。

  • 指令格式

    • LDM{cond}<模式> Rn{!},<reglist>{^}
    • STM{cond} <模式> Rn{!},<reglist>{^}
    • 指令格式說明
      • Rn:表示基址寄存器,裝有傳送數據的初始地址,Rn不允許為R15(即PC)
      • Rn后綴 **“!” **:表示最后的地址寫回到Rn中
      • reglist:表示寄存器列表,其中包含一個或多個寄存器。當寄存器不連續時,中間使用“,”隔開。
        • 格式例子:{R1,R2,R6-R9}
        • 列表寄存器和存儲器地址的關系規則:編號低的寄存器對應于存儲器中低地址單元,編號高的寄存器對應于存儲器中高地址單元
    • 后綴 “^” 說明
      • 寄存器列表不包含PC
        • 使用后綴“^”進行數據傳送時,加載/存儲的是用戶模式的寄存器,而不是當前模式的寄存器
      • 寄存器列表包含有PC
        • 除了正常的多寄存器傳送外,還要將SPSR拷貝到CPSR中。該用法可用于異常處理返回
      • 禁用情況:后綴“^”不允許在用戶模式或系統模式下使用。 因為它們沒有SPSR
    • Rn在寄存器列表中且使用后綴“!”
      • 對于STM指令,若Rn為寄存器列表中的最低序號的寄存器,則會將Rn的初值保存;
      • 其它情況下Rn的編譯無法通過。
    • 地址字對齊:這些指令尋址是字對齊的,即忽略地址位[1:0]。
  • 指令編碼格式

  • 模式項

    • LDM/STM的主要用途是現場保護、數據復制和參數傳送等。

    • 其模式有如下8種(前面4種用于數據塊的傳輸(為存儲操作), 后面4種是堆棧操作):

      類型每次基址寄存器的操作傳送起始地址Rn序號的變化
      IA先傳送數據,后基地址加4(Rn)增加
      IB先基地址加4,后傳送數據(Rn)+4增加
      DA先傳送數據,后基地址減4(Rn)減少
      DB先基地址減4,后傳送數據(Rn)-4減少
      類型堆棧類型彈出(pop)指令壓入(push)指令
      FA遞增滿堆棧LDMFASTMFA
      FD遞減滿堆棧LDMFDSTMFD
      EA遞增空堆棧LDMEASTMEA
      ED遞減空堆棧LDMEDSTMED
      • 堆棧操作與批量傳輸對應

        尋址方式說明pop=LDMpush=STM
        FA遞增滿LDMFALDMDASTMFASTMIB
        FD遞減滿LDMFDLDMIASTMFDSTMDB
        EA遞增空LDMEALDMDBSTMEASTMIA
        ED遞減空LDMEDLDMIBSTMEDSTMDA
  • 示例

    • 這里能看出來序號高的寄存器一定會存/取地址高的地址
三、單寄存器交換指令(SWP)
  • SWP指令用于將一個存儲單元(該單元地址放在寄存器Rn中)的內容讀取到一個寄存器Rd中,同時將另一個寄存器Rm的內容寫入到該存儲單元中

  • 交換指令是一個原子操作,也就是說,在連續的總線操作中讀/寫一個存儲單元,在操作期間阻止其它任何指令對該存儲單元的讀寫

  • 指令格式

    • SWP{cond}{B} Rd,Rm,[Rn]
    • B為可選后綴,若有B,則交換無符號字節,否則交換32位字
    • Rd為被加載的寄存器
    • Rm的數據用于存儲到Rn所指的地址中,若Rm與Rd相同,則為寄存器與存儲器內容進行交換
    • Rn為要進行數據交換的存儲器地址,Rn不能與Rd和Rm相同。
    • 功能:將一個內存單元[Rn]的內容讀取到一個寄存器Rd中,同時將另一個寄存器Rm的內容寫入到該內存單元中
  • 指令編碼格式

  • 指令舉例

    • SWP R1,R1,[R0];將R1的內容與R0指向的存儲單元的內容進行交換。
    • SWPB R1,R2,[R0];將R0指向的存儲單元的內容讀取1字節數據到R1中(高24位清零),并將R2的內容寫入到該內存單元中(最低字節有效)
3.3.5 雜項指令
  • 主要由兩種類型指令組成,程序狀態寄存器操作指令、中斷操作指令,一共有5條指令。
    • 狀態寄存器操作指令:
      • MRS:讀程序狀態寄存器指令
      • MSR:寫程序狀態寄存器指令
    • 異常中斷操作指令:
      • SWI: 軟件中斷指令
      • BKPT:斷點指令(v5T體系)
      • CLZ: 前導0計數(v5T體系)
一、程序狀態寄存器處理指令
  • ARM指令中有兩條指令,用于在狀態寄存器通用寄存器之間傳送數據。修改狀態寄存器一般是通過“讀取-修改-寫回”三個步驟的操作來實現的。
  1. MRS–讀狀態寄存器指令

    • 指令格式:MRS{cond} Rd,psr ; Rd <- psr

    • 把**狀態寄存器psr(CPSR或SPSR)**的內容傳送到目標寄存器中。

      • Rd —— 目標寄存器。Rd不允許為R15。
      • psr —— CPSR或SPSR。
    • 指令編碼格式

      • 注意:在ARM處理器中,只有MRS指令可以將狀態寄存器CPSR或SPSR讀出到通用寄存器中。
  2. MSR–寫狀態寄存器指令

    • 在ARM處理器中,只有MSR指令可以直接設置狀態寄存器CPSR或SPSR

    • 指令格式如下:

      • MSR{cond} psr_fields,#immed

      • MSR{cond} psr_fields,Rm

      • 其中:

        • psr:CPSR或SPSR

        • immed:要傳送到狀態寄存器指定域的8位立即數

        • Rm:要傳送到狀態寄存器指定域的數據的源寄存器

        • fields:指定傳送的區域。fields可以是以下的一種或多種:

          • c 控制域 (psr[7…0]);

          • x 擴展域(psr[15…8]);(暫未用)

          • s 狀態域 (psr[23…16]);(暫未用)

          • f 標志位域 (psr[31…24])。

    • 指令舉例

      • MSR CPSR_cxsf,R0 ;傳送R0的內容到CPSR
      • MSR SPSR_cxsf,R0 ;傳送R0的內容到SPSR
      • MSR CPSR_c,R0 ;傳送R0的內容到CPSR,但僅僅修改CPSR中的控制位域
      • MSR CPSR_cfxs,R0 ;傳送R0的內容到CPSR,修改所有域
    • 注 意:

      • 控制域的修改問題:只有在特權模式下才能修改狀態寄存器的控制域[7:0],以實現處理器模式轉換,或設置開/關異常中斷 。
      • T控制位的修改問題:程序中不能通過MSR指令,直接修改CPSR中的T控制位來實現ARM狀態/Thumb狀態的切換,必須使用BX指令完成處理器狀態的切換
      • 用戶模式下能夠修改的位:在用戶模式只能修改“標志位域”,不能對CPSR[23:0]做修改。
      • S后綴的使用問題:在MRS/MSR指令中不可以使用S后綴
二、異常中斷產生指令
  • 異常中斷指令可以分為以下幾種:
    • SWI: 軟件中斷指令
    • BKPT:斷點指令(v5T及以上體系)
    • CLZ: 前導0計數(v5T及以上體系)
  1. SWI——軟件中斷指令

    • 軟件中斷指令SWI產生軟件異常中斷,用來實現用戶模式到特權模式的切換

    • 用于在用戶模式下對操作系統中特權模式的程序的調用;

    • 它將處理器置于管理(svc)模式,中斷矢量地址為0x08。

    • 指令格式如下:SWI {<cond>} <24位立即數>

      • 24位立即數,指定用戶程序調用系統例程的類型,相關參數通過寄存器傳遞,當指令中24位立即數被忽略時(立即數為0),用戶程序調用系統例程的類型由通用寄存器R0決定,同時參數通過其它寄存器傳遞
    • 指令編碼格式

    • 說明:

      • 主要用于用戶程序調用操作系統的API。
      • 參數傳遞通常有兩種方法:
        • 指令中的24bit立即數指定API號,其它參數通過寄存器傳遞。
        • 忽略指令中的24bit立即數,r0指定API號,其它參數通過其它寄存器傳遞。
    • 舉例

      • 軟中斷號在指令中,不傳遞其它參數:
        • SWI 10 ;中斷類型號為10(注:沒有#號)
        • SWI 0x123456 ;中斷類型號為0x123456
      • 軟中斷號在指令中,其它參數在寄存器中傳遞:
        • MOV R0,#34 ;準備參數
        • SWI 12 ;調用12號軟中斷
      • 不用指令中的立即數,軟中斷類型號和其它參數都在寄存器中傳遞:
        • MOV R0,#12 ;準備中斷類型號
        • MOV R1,#34 ;準備參數
        • SWI 0 ;進入軟中斷。
  2. BKPT——斷點指令(了解)

    • 斷點中斷指令BKPT用于產生軟件斷點,供調試程序用。
    • v5T及以上體系使用。
    • 指令格式如下: BKPT { immed_16}
      • immed_16:16位的立即數。該立即數被調試軟件用來保存額外的斷點信息。
    • 斷點指令用于軟件調試;它使處理器停止執行正常指令而進入相應的調試程序。
  3. CLZ——前導0計數指令(了解)

    • 前導0計數指令CLZ 對Rm中的前導0的個數進行計數,結果放到Rd中。

    • v5T及以上體系使用。

    • 指令格式:CLZ{<cond>} Rd, Rm

    • 舉例如下:

       MOV   R2, #0X17C00 ;R2=0b0000 0000 0000 0001 0111 1100 0000 0000      CLZ   R3, R2    		;R3=15
      

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

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

相關文章

Spring Boot接口通用返回值設計與實現最佳實踐

一、核心返回值模型設計&#xff08;增強版&#xff09; package com.chat.common;import com.chat.util.I18nUtil; import com.chat.util.TraceUtil; import lombok.AllArgsConstructor; import lombok.Data; import lombok.Getter;import java.io.Serializable;/*** 功能: 通…

2025年上半年軟件架構師考試回憶版【持續更新】

文章目錄 案例分析1、端AI相對于云AI的優勢2、redis持久化&#xff0c;主從庫3、解釋器架構風格4、知識圖譜5、區塊鏈 論文1、基于事件驅動的模型2、多模型數據庫及其應用3、負載均衡設計方法4、論軟件測試理論及其應用 考試感受 2025年軟件考試架構考試于5月24日如期舉行&…

Windows下編譯Zipios

本文記錄在Windows下編譯Zipios的流程。 注1&#xff1a;文章內容會不定期更新。 零、環境 操作系統Windows 11VS Code1.92.1Git2.34.1Visual StudioVisual Studio Community 2022CMake3.22.1 一、安裝依賴 二、編譯 2.1 下載代碼 git clone https://github.com/Zipios/Zi…

SOC-ESP32S3部分:11-任務創建

飛書文檔https://x509p6c8to.feishu.cn/wiki/EH3owsPahisvl6kL6k3cqaQ3n0g 在我們學習單片機的時候&#xff0c;main函數入口中一般有一個while大循環在不停輪詢&#xff0c;如果我們需要實現多種不同的業務&#xff0c;就需要用到狀態機&#xff0c;根據不同時刻的要求執行不…

[Git] 如何進行版本回退

版本控制系統最重要的能力之一&#xff0c;就是能夠輕松地在項目的不同歷史版本之間切換。有時&#xff0c;你可能發現最近的修改引入了嚴重問題&#xff0c;或者需要回到之前的某個節點重新開始。這時&#xff0c;“版本回退”功能就派上用場了。 版本回退&#xff1a;反方向…

易貝平臺關鍵字搜索技術深度解析

一、核心搜索機制 關鍵詞匹配原理 采用TF-IDF算法計算關鍵詞權重 支持同義詞擴展&#xff08;如"phone"匹配"cellphone"&#xff09; 標題權重 > 副標題 > 商品描述 搜索排序因素 # 搜索權重模擬計算 def calculate_rank(keyword, item): title…

深度剖析 MCP SDK 最新版:Streamable HTTP 模式

好記憶不如爛筆頭&#xff0c;能記下點東西&#xff0c;就記下點&#xff0c;有時間拿出來看看&#xff0c;也會發覺不一樣的感受. 目錄 一、概述 二、快速上手&#xff1a;開啟 Streamable HTTP 服務端開啟 客戶端連接 三、深入兩個核心參數 stateless_http json_resp…

樹莓派開箱上手教程(無需顯示器版)

樹莓派開箱上手教程&#xff08;無需顯示器版&#xff09; 硬件準備 名稱參數電源適配器5V電源適配器&#xff0c;至少需要3A的額定電流&#xff0c;配備USB Type-C輸出接頭microSD卡用來將樹莓派的操作系統安裝到上邊&#xff0c;至少需要8GB容量&#xff0c;一般建議16GB及以…

MySQL強化關鍵_015_存儲過程

目 錄 一、概述 1.說明 2.優點 3.缺點 二、存儲過程的操作 1.創建 2.調用 3.查看 4.刪除 三、變量 1.系統變量 &#xff08;1&#xff09;說明 &#xff08;2&#xff09;查看系統變量 &#xff08;3&#xff09;設置系統變量 2.用戶變量 &#xff08;1&…

動態規劃dp

這里寫目錄標題 動態規劃01背包完全背包多重背包混合背包二維費用的背包分組背包有依賴的背包背包問題求方案數背包問題求具體方案數位 DP狀壓 DP常用例題 動態規劃 01背包 有 n n n 件物品和一個容量為 W W W 的背包&#xff0c;第 i i i 件物品的體積為 w [ i ] w[i] w…

arcgis js統計FeatureLayer的橢球面積、平面面積

1、導入依賴 import FeatureLayer from arcgis/core/layers/FeatureLayer import { geodesicArea, planarArea, simplify } from arcgis/core/geometry/geometryEngine; import { project, load as projectionLoad } from arcgis/core/geometry/projection2、初始化project o…

2.2.1 05年T2

引言 本文將從一預習、二自習、三學習、四復習等四個階段來分析2005年考研英語閱讀第二篇文章。為了便于后續閱讀&#xff0c;我將第四部分復習放在了首位。 四、復習 方法&#xff1a;錯誤思路分析總結考點文章梳理 4.1 錯題分析 題目&#xff1a;26&#xff08;細節題&…

Java 連接并操作 Redis 萬字詳解:從 Jedis 直連到 RedisTemplate 封裝,5 種方式全解析

引言 在分布式系統和高并發場景中&#xff0c;Redis 作為高性能內存數據庫的地位舉足輕重。對于 Java 開發者而言&#xff0c;掌握 Redis 的連接與操作是進階必備技能。然而&#xff0c;從基礎的 Jedis 原生客戶端到 Spring 封裝的 RedisTemplate&#xff0c;不同連接方式的原…

談談對《加密算法》的理解

文章目錄 一、什么是加密算法&#xff1f;二、常見的加密算法有哪些&#xff1f;2.1 對稱加密2.2 非對稱加密2.3 哈希算法 三、加密算法代碼展示3.1 MD5加密3.2 秘鑰加密3.3 AES加密解密 四、加密算法的使用場景 一、什么是加密算法&#xff1f; 加密算法是一種通過數學方法將…

Fuzz 模糊測試篇JS 算法口令隱藏參數盲 Payload未知文件目錄

1 、 Fuzz 是一種基于黑盒的自動化軟件模糊測試技術 , 簡單的說一種懶惰且暴力的技術融合了常見 的以及精心構建的數據文本進行網站、軟件安全性測試。 2 、 Fuzz 的核心思想 : 口令 Fuzz( 弱口令 ) 目錄 Fuzz( 漏洞點 ) 參數 Fuzz( 利用參數 ) PayloadFuzz(Bypass)…

哈希表的實現(下)

目錄 前言 開散列概念 開散列實現 Insert 優化 Find Erase 前言 上一章節我們用閉散列實現了一下哈希表&#xff0c;但存在一些問題&#xff0c;比如空間浪費比較嚴重&#xff0c;如果連續一段空間都已經存放值&#xff0c;那么在此位置插入新值的時候就會一直挪動&…

再談Linux 進程:進程等待、進程替換與環境變量

目錄 1.進程等待 為什么需要進程等待&#xff1f; 相關系統調用&#xff1a;wait()和waitpid() wait(): waitpid(): 解析子進程狀態&#xff08;status&#xff09; 2.進程替換 為什么需要進程替換&#xff1f; 相關系統調用&#xff1a;exec函數家族 3.環境變量 ?…

基于深度學習的無線電調制識別系統

基于深度學習的無線電調制識別系統 本項目實現了一個基于深度學習的無線電調制識別系統&#xff0c;使用LSTM&#xff08;長短期記憶網絡&#xff09;模型對不同類型的 無線電信號進行自動分類識別。該系統能夠在不同信噪比(SNR)條件下&#xff0c;準確識別多種調制類型&#…

Python 爬蟲之requests 模塊的應用

requests 是用 python 語言編寫的一個開源的HTTP庫&#xff0c;可以通過 requests 庫編寫 python 代碼發送網絡請求&#xff0c;其簡單易用&#xff0c;是編寫爬蟲程序時必知必會的一個模塊。 requests 模塊的作用 發送網絡請求&#xff0c;獲取響應數據。 中文文檔&#xf…

隨機森林(Random Forest)學習

隨機森林是一種基于集成學習的機器學習算法&#xff0c;屬于Bagging&#xff08;Bootstrap Aggregating&#xff09;方法的一種擴展。它通過組合多個決策樹來提升模型的泛化能力和魯棒性&#xff0c;廣泛用于分類、回歸和特征選擇任務。 1.隨機森林核心思想 1.1少數服從多數 在…