簡體   English   中英

arm-none-eabi-as bne.n 行為不端(或者我這樣做)

[英]arm-none-eabi-as bne.n misbehaves (or I do)

我有時不得不涉足一些匯編程序,並且不太確定指令的正確使用。 在調查什么應該是最簡單的延遲循環時,我得到了一個意想不到的結果,我的問題是:我是否濫用了指令,或者下面的代碼是否實際上是編譯器錯誤。

如果答案是“編譯器錯誤”:請注意,我知道那里有較新版本的 arm-none-eabi-as。 問題不是“讓這段代碼工作”,而是正確使用匯編指令的問題。 目標系統是普通的 STM32F1xx 系列 Cortex-m3 處理器。

以下代碼:

        .syntax unified
        .cpu  cortex-m3
        .thumb
    
        .align 1
        .global myDelayWorks       
        .thumb_func
myDelayWorks:   
.FileLocalLabel:
        subs  r0,#1
        bne.n .FileLocalLabel
        bx    lr
            
        .align 1
        .global myDelayFails       
        .thumb_func
myDelayFails:
        subs  r0,#1
        bne.n myDelayFails
        bx    lr

編譯為以下內容(使用 arm-none-eabi-as --version GNU 匯編器(用於 ARM 嵌入式處理器的 GNU 工具)2.24.0.20150604):

   8                myDelayWorks:   
   9                .FileLocalLabel:
  10 0000 0138              subs  r0,#1
  11 0002 FDD1              bne.n .FileLocalLabel
  12 0004 7047              bx    lr
  13                        
  14                        .align 1
  15                        .global myDelayFails       
  16                        .thumb_func
  17                myDelayFails:
  18 0006 0138              subs  r0,#1
  19 0008 FED1              bne.n myDelayFails
  20 000a 7047              bx    lr

由於myDelayFails被聲明為.global ,因此似乎出現了錯誤分支偏移的問題。

我想你擔心的是機器代碼FED1中編碼的位移(這是錯誤的字節序,應該是D1FE以匹配通常的符號)似乎是 -4,它應該是 -6? 那是因為它最終由 linker 計算,而不是匯編程序。

匯編器留在該字段中的內容沒有直接意義(有時是鏈接器在地址計算中包含的偏移量),但在 object 文件中會有一個重定位條目,告訴 linker 在那里插入正確的位移到 label myDelayFails

所以這一切都很正常。 如果您反匯編 linker 生成的實際可執行文件,您應該會看到正確的位移。

全局和非全局標簽在這方面表現不同也是正常的。 對於同一節中的非全局 label,匯編器可以准確地看到目標 label 相對於分支的位置(即使它不知道它們的絕對地址),因此它可以自己計算和插入位移。 對於全局 label,它可能位於匯編器不知道其最終位置的另一個部分,或者完全在不同的源文件中定義,因此匯編器將其留給 linker。

在這種情況下,全局 label 在當前文件中定義,因此匯編程序原則上可以自己計算位移。 我不確定他們為什么選擇將其留給 linker。 如果出於某種原因這樣做有用的話,linker 可能會重新定義符號myDelayFails

正如接受的答案中所建議的,鏈接匯編器結果將修復全局引用,並確定偏移量足夠小以使用 16 位相對條件分支。 偏移量似乎關閉是匯編器列表生成的產物。

使用原始代碼,執行以下操作以獲取二進制圖像:

arm-none-eabi-as -ahls=myDelay.lst -o myDelay.o myDelay.s
arm-none-eabi-ld -o myDelay.out myDelay.o
arm-none-eabi-ld: warning: cannot find entry symbol _start; defaulting to 00008000
arm-none-eabi-objcopy -Obinary myDelay.out myDelay.bin 

然后對生成的二進制文件進行 hexdump:

00000000: 0138 fdd1 7047 0138 fdd1 7047            .8..pG.8..pG

說明兩個套路的結果確實是一樣的。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM