簡體   English   中英

排序ARM程序集

[英]Sorting ARM Assembly

我是新手。 我在理解內存ARM內存映射時遇到困難。

我找到了簡單排序算法的示例

    AREA ARM, CODE, READONLY

    CODE32
    PRESERVE8

    EXPORT __sortc
    ; r0 = &arr[0]
    ; r1 = length 

__sortc
    stmfd sp!, {r2-r9, lr}

    mov r4, r1                  ; inner loop counter
    mov r3, r4
    sub r1, r1, #1
    mov r9, r1                  ; outer loop counter                        

outer_loop
    mov r5, r0
    mov r4, r3

inner_loop
    ldr r6, [r5], #4
    ldr r7, [r5]
    cmp r7, r6

    ; swap without swp
    strls r6, [r5]
    strls r7, [r5, #-4] 

    subs r4, r4, #1
    bne inner_loop

    subs r9, r9, #1  
    bne outer_loop  

    ldmfd sp!, {r2-r9, pc}^

    END

並且此匯編程序應從C代碼中以這種方式調用

#define MAX_ELEMENTS    10

extern void __sortc(int *, int);

int main()
{
        int arr[MAX_ELEMENTS] = {5, 4, 1, 3, 2, 12, 55, 64, 77, 10};

    __sortc(arr, MAX_ELEMENTS);

    return 0;
}

據我了解,此代碼在堆棧上創建整數數組,並調用在匯編中實現的_sortc函數。 此函數從堆棧中獲取此值並對其進行排序,然后放回堆棧中。 我對嗎 ?

我想知道如何僅使用匯編來實現此示例。

例如定義整數數組

DCD 3, 7, 2, 8, 5, 7, 2, 6

BTW DCD聲明的變量存儲在內存中的位置?

如何以這種方式聲明的值進行運算? 請說明如何僅使用原始數據就不使用任何C代碼,甚至不使用堆棧就可以使用匯編來實現此目的。

我正在為ARM7TDMI體系結構編寫

AREA ARM, CODE, READONLY這標志着源代碼部分的開始。

使用類似的AREA myData, DATA, READWRITE您可以在開始部分的地方開始定義data1 DCD 1,2,3類的數據,這將編譯為三個單詞,連續字節中包含值1,2,3,標簽data1指向第一個單詞的第一個字節。 (一些來自Google的AREA文檔)。

加載可執行文件后,這些文件將在物理內存中的位置取決於鏈接可執行文件的方式(鏈接器正在使用腳本文件來幫助他確定將哪個區域放置在何處,以及如何創建符號表以由可執行文件加載器進行動態重定位,通過編輯鏈接描述文件,您可以調整代碼和數據的放置位置,但通常不需要這樣做。

此外,鏈接器腳本和匯編器指令也會影響可用堆棧的大小以及它在物理內存中的映射位置。

因此,對於您的特定平台:谷歌用於Web上的內存映射,並檢查鏈接描述文件(開始時只需使用鏈接器選項來生成.map文件,以查看將代碼和數據定位在何處)。

因此,您可以在某個數據區域中聲明該數組,然后使用該數組,將符號data1加載到寄存器中(“加載data1的地址”),然后使用該數組從該地址中獲取內存內容。

或者,您可以先將所有數字放入堆棧中(可能由可執行文件的OS加載程序將其設置為合理的值),然后使用堆棧指針在代碼中進行操作以訪問其中的數字。

您甚至可以將一些值DCDCODE區域,因此這些字將在可執行加載程序映射為只讀的內存指令之間結束。 您可以讀取這些數據,但是寫入它們可能會導致崩潰。 當然,您不應該偶然地將它們作為指令執行(忘記在DCD之前放置一些ret / jump指令)。


沒有堆棧

好吧,這很棘手,您必須小心不要使用任何呼叫/等。 並禁用中斷等。基本上任何需要堆棧的東西。

當人們編寫引導加載程序代碼時,通常他們會在前幾條指令中盡快設置一些臨時堆棧,因此他們可以在基本設置整個環境或加載操作系統之前使用基本的堆棧功能。 臨時堆棧的空間通常在代碼中/之后保留,或者根據重置后定義的機器狀態保留未使用的內存空間。

如果您精疲力盡,沒有操作系統,通常所有內存在重置后都是可寫的,因此您可以根據需要混合代碼和數據(只是在數據周圍跳躍,而不是偶然地執行它們),而無需使用AREA定義。

但是,無論您是要在某些OS的用戶空間中創建應用程序(因此,如堆棧和數據區之類的定義都很好並且可以方便地使用它們),還是要創建必須用於自行設置所有內容(更困難,因此我建議首先進入某些OS的用戶領域,使用clib初始化C包裝器也很方便,因此您可以從ASM調用printf東西以方便輸出)。


如何使用以這種方式聲明的值進行操作

在機器碼中,值的聲明方式無關緊要。 重要的是,如果您有內存的地址,並且知道結構,那么如何將數據存儲在那里。 然后,您可以使用所需的任何說明,以所需的任何方式與他們合作。 因此,該asm示例的主體不會發生變化,如果您在ASM中分配數據,您將像C一樣將指針作為參數傳遞給它。


編輯:一些未經測試而盲目完成的示例,可能需要進一步修復語法才能適用於OP(或者甚至可能存在一些錯誤,並且根本無法使用,如果可以,請在評論中告訴我):

    AREA myData, DATA, READWRITE

SortArray
    DCD     5, 4, 1, 3, 2, 12, 55, 64, 77, 10
SortArrayEnd

    AREA ARM, CODE, READONLY

    CODE32
    PRESERVE8

    EXPORT __sortasmarray

__sortasmarray
    ; if "add r0, pc, #SortArray" fails (code too far in memory from array)
    ; then this looks like some heavy weight way of loading any address
    ; ldr   r0, =SortArray
    ; ldr   r1, =SortArrayEnd

    add   r0, pc, #SortArray    ; address of array
    ; calculate array size from address of end
    ; (as I couldn't find now example of thing like "equ $-SortArray")
    add   r1, pc, #SortArrayEnd
    sub   r1, r1, r0
    mov   r1, r1, lsr #2
    ; do a direct jump instead of "bl", so __sortc returning
    ; to lr will actually return to called of this
    b     __sortc

    ; ... rest of your __sortc assembly without change    

您可以通過C代碼將其調用為:

extern void __sortasmarray();

int main()
{
    __sortasmarray();
    return 0;
}

除其他外,我還使用了這種介紹性的ARM匯編語言來刷新我的ARM asm內存,但我仍然擔心這可能無法正常工作。

如您所見,我沒有更改__sortc 任何 __sortc 因為訪問堆棧內存或“ dcd”內存沒有區別,所以它是同一台計算機內存。 獲得特定單詞的地址后,您就可以使用該地址ldr / str它的值。 __sortc接收數組中第一個單詞的地址以在兩種情況下進行排序,從那里開始只是用於存儲它,而沒有任何上下文說明如何在源中定義,分配,初始化存儲等。只要它是可寫的,就可以__sortc。

因此,我唯一與“ dcd”相關的事情是加載數組地址,並且快速搜索ARM示例表明它可以通過幾種方式來完成,這種add rX, pc, #label方式是最佳的,但僅適用於+- 4K范圍? 還有偽指令ADR rX, #label做同樣的事情,在范圍問題的情況下可能會切換到其他指令? 對於任何范圍,它看起來都像ldr rX, = label形式,盡管我不確定它是偽指令還是它是如何工作的,請查看一些教程並反匯編機器代碼以查看其編譯方式。

學習所有ARM程序集的特性以及如何加載數組的地址取決於您,我目前不需要ARM ASM,因此我沒有深入研究這些細節。

並且應該有一些equ方法來定義數組的長度,而不是從結束地址中的代碼中對其進行計算,但是我找不到任何示例,而且我也不會閱讀完整的Assembler文檔來了解其所有指令(在gas我認為ArrayLength equ ((.-SortArray)/4)將起作用)。

暫無
暫無

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

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