我們知道ARM CPU中有一條被廣泛使用的指令LDR,它主要是用來從存儲器(確切地說是地址空間)中裝載數(shù)據(jù)到通用寄存器。但不論是ARMASM還是GNU ARM AS,都提供了一條與之同名的偽指令LDR,而在實(shí)際中使用該偽指令的情況也較多,那他們有什么不同呢?下面我談?wù)勎业睦斫狻?/span> 由于我使用GNU工具鏈,所以以下的內(nèi)容都以GNU AS的ARM語法為準(zhǔn)。 LDR偽指令的語法形式如下: LDR 這個常量表達(dá)式 1 .equ STACK_BASE, 0x0c002000 2 .equ STACK_SIZE, 0x00001000 3 4 .text 5 ldr sp, = STACK_BASE 6 ldr sl, = STACK_BASE - STACK_SIZE 7 ldr pc, = entry 這是一個合法的匯編文件,它把堆?;吩O(shè)為0x0c002000,棧限設(shè)為0x0c001000,然后跳到entry所標(biāo)識的C程序中執(zhí)行。 下面我們假設(shè)符號“entry”的地址為0x0c000000。 我們?nèi)绻焉厦娲a寫成: 1 .text 2 mov sp, #0x0c002000 3 mov sl, #0x0c001000 4 mov pc, #0x0c000000 匯編器會報(bào)錯: demo.s: Assembler messages: demo.s:2: Error: invalid constant -- `mov sp,#0x0c002000' demo.s:3: Error: invalid constant -- `mov sl,#0x0c001000' 說起這個錯誤的原因可就話長了,簡而言之是因?yàn)镽ISC有一個重要的概念就是所有指令等長。在ARM指令集中,所有指令長度為4字節(jié)(Thumb指令是2 字節(jié))。那問題就來了,4字節(jié)是不可能同時存的下指令控制碼和32位立即數(shù)的,那么我要把一個32位立即數(shù)(比如一個32位地址值)傳送給寄存器該怎么 辦? RISC CPU提供一個通用的方法就是把地址值作為數(shù)據(jù)而不是代碼,從存儲器中相應(yīng)的位置讀入到寄存器中,待會我們會看到這樣的例子。 此外ARM還提供另一種方案。由于傳送類指令的指令控制碼部分(cond, opcode, S, Rd, Rn域)占去了20個字節(jié),那能提供給立即數(shù)的就只剩12個位了。 ARM并未使用這12個位來直接存一個12位立即數(shù),而是使用了類似有效數(shù)字一樣的概念,只存8個字節(jié)的有效位和一個4位的位偏移量(偏移單位為2)。這個東西在ARM被叫做術(shù)語immed_8,有興趣的人可以找資料了解一下,到處都有介紹。 可以看出ARM的這個方法能直接使用的立即數(shù)是相當(dāng)有限的,像0xfffffff0這樣的數(shù)顯然無法支持。別著急,ARM的傳送類指令中還有一個MVN指 令可以解決該問題。顯然0x0000000f是一個有效立即數(shù),MVN會先將其取反再傳送,這樣有效立即數(shù)的范圍又?jǐn)U充了一倍。 可就算如此仍有大量的32位立即數(shù)是無效的,比如上面那個例子中的0x0c002000和0x0c001000。面對這種問題一是使用RISC的通用方法,二是分次載入。 比如可以這樣載入0x0c002000: 1 .text 2 mov sp, #0x0c000000 3 add sp, sp, #0x00002000 或者: .text mov sp, #0x0c000000 orr sp, sp, #0x00002000 感覺很狡猾是吧,呵呵。但是要注意它和方法一的一大區(qū)別:需要多條指令。那么在一些對指令數(shù)目有限制的場合就無法使用它,比如異常向量表處要做長跳轉(zhuǎn)(超過±32MB)的話就只能用方法一;還有就是在同步事務(wù)中該操作不是原子的,因此可能需要加鎖。 扯了這么多再回到LDR偽指令上來。顯然上面的內(nèi)容是復(fù)雜繁瑣的,如果然程序員在寫程序的時候還要考慮某個數(shù)是不是immed_8一定超級麻煩,因此為了減輕程序員的負(fù)擔(dān)才引入了LDR偽指令。 你一定很好奇第一段代碼demo.s被GNU AS變成了什么,好,讓我們在Linux環(huán)境下執(zhí)行下面的命令: arm-elf-as -o demo.o demo.s arm-elf-objdump -D demo.o 結(jié)果: demo.o: file format elf32-littlearm Disassembly of section .text: 00000000 <.text>: 0: e59fd004 ldr sp, [pc, #4] ; c <.text+0xc> 4: e59fa004 ldr sl, [pc, #4] ; 10 <.text+0x10> 8: e59ff004 ldr pc, [pc, #4] ; 14 <.text+0x14> c: 0c002000 stceq 0, cr2, [r0] 10: 0c001000 stceq 0, cr1, [r0] 14: 00000000 andeq r0, r0, r0 Disassembly of section .data: 由于entry還沒連上目標(biāo)地址,objdump反匯編會認(rèn)為是0,我們先不管它。另外兩條LDR偽指令變成了實(shí)際的LDR指令!但目標(biāo)很奇怪,都是[pc, #4]。那好我們看看[pc, #4]是什么。 我們知道pc中存放的是當(dāng)前指令的下下條指令的位置,也就是. + 8。那么上面的第一條指令ldr sp, [pc, #4]中的pc就是0x8,pc + 4就是0xc,而[0xc]的內(nèi)容正是0x0c002000;同理,第二條ldr指令也是如此。顯然這里L(fēng)DR偽指令采用的是RISC通用的方法。 另外要說的是,如果LDR的是一個immed_8或者immed_8的反碼數(shù),則會直接被解釋成mov或mvn指令。如ldr pc, = 0x0c000000會被解釋成mov pc, 0x0c000000。 最后一點(diǎn)補(bǔ)充,我發(fā)現(xiàn)arm-elf-gcc通常都用累加法。如C語句中的i = 0x100ffc04;會變成類似于以下的語句: mov r0, #0x10000004 add r0, r0, #0x000ff000 add r0, r0, #0x00000c00 ... 原因不詳。
上一篇:在嵌入式Linux系統(tǒng)(OK6410)中移植Boa 服務(wù)器
下一篇:OK6410 rmmod卸載模塊失?。篘o such file or directory
推薦閱讀最新更新時間:2025-06-17 20:27


設(shè)計(jì)資源 培訓(xùn) 開發(fā)板 精華推薦
- Microchip 升級數(shù)字信號控制器(DSC)產(chǎn)品線 推出PWM 分辨率和 ADC 速度業(yè)界領(lǐng)先的新器件
- 意法半導(dǎo)體STM32MP23x:突破成本限制的工業(yè)AI應(yīng)用核心
- 意法半導(dǎo)體推出用于匹配遠(yuǎn)距離無線微控制器STM32WL33的集成的匹配濾波芯片
- ESP32開發(fā)板連接TFT顯示屏ST7789跳坑記
- 如何讓ESP32支持analogWrite函數(shù)
- LGVL配合FreeType為可變字體設(shè)置字重-ESP32篇
- 使用樹莓派進(jìn)行 ESP32 Jtag 調(diào)試
- ESP32怎么在SPIFFS里面存儲html,css,js文件,以及網(wǎng)頁和arduino的通訊
- ESP32 freeRTOS使用測試
- 基于STM32的數(shù)字示波器設(shè)計(jì)方案(完整資料)
- v3s開發(fā)板
- tpa 3118功放
- 使用 Silicon Labs 的 EZR32WG330F256R55G 的參考設(shè)計(jì)
- LT3468ES5 演示板,閃光燈電容器充電器高壓電源,2.8V 至 8Vin,320Vout
- ESP32物聯(lián)網(wǎng)控制臺
- 使用 MaxLinear, Inc 的 AS431C 的參考設(shè)計(jì)
- 適用于STM32L011K4 MCU的STM32 Nucleo-32開發(fā)板,支持Arduino nano連接
- 【RA】瑞薩mcu示波器
- LOL專屬鍵盤
- MediaTek針對高端市場發(fā)布迅鯤?900T,坐穩(wěn)安卓平板第一位
- ZDS2022示波器百集實(shí)操視頻之40:斜率觸發(fā)
- 美亞柏科:已對虛擬經(jīng)濟(jì)等開展技術(shù)研究,應(yīng)對未來元宇宙
- OPPO Find X5 Lite新機(jī)解密,為Reno7 5G國際改名版
- 開關(guān)電源怎么測試紋波_示波器測試開關(guān)電源紋波的方法
- 消息稱三星 5 月將搶先生產(chǎn)蘋果 iPhone 15 系列 OLED 屏幕,京東方遇光泄漏難題
- BlackBerry QNX 推出超可擴(kuò)展、高性能計(jì)算操作系統(tǒng)
- 利用定制用戶界面或測試自動化功能簡化示波器的操作過程
- STM32F1_ FSMC讀寫外部SRAM
- 國芯科技發(fā)布全球首款48V安全氣囊芯片,引領(lǐng)智能汽車新紀(jì)元
- 亞馬遜全球部署100萬臺機(jī)器人
- 自動駕駛只用激光雷達(dá)進(jìn)行感知會有哪些問題?
- 為什么電源紋波測試結(jié)果與理論設(shè)計(jì)如此之大?
- UWB信標(biāo)與LoRa基站網(wǎng)關(guān)數(shù)據(jù)區(qū)別在哪里?
- 什么是AI 同傳技術(shù)
- 人工智能處理器和加速器到底是什么?
- PWM控制(脈沖寬度調(diào)制)的基本原理是什么
- 如何設(shè)計(jì)帶集成運(yùn)放構(gòu)成的方波發(fā)生器
- DSP調(diào)度算法的基本概念和原理