簡體   English   中英

從gcc輸出中了解程序集

[英]Understanding assembly from a gcc output

我正在做一個關於計算機基礎知識的高中課程,我正在嘗試理解匯編代碼並在C中創建一個hello world並用匯編代碼編譯它。 據我所知,“mov r0,r3”將數據從寄存器3移動到寄存器0.但是,我如何計算出r3的值是什么?

下面是我用來理解的匯編代碼:

.arch armv6
.eabi_attribute 27, 3
.eabi_attribute 28, 1
.fpu vfp
.eabi_attribute 20, 1
.eabi_attribute 21, 1
.eabi_attribute 23, 3
.eabi_attribute 24, 1
.eabi_attribute 25, 1
.eabi_attribute 26, 2
.eabi_attribute 30, 6
.eabi_attribute 34, 1
.eabi_attribute 18, 4
.file   "hello.c"
.section    .rodata
.align  2
.LC0:
    .ascii  "Hello World\000"
    .text
    .align  2
    .global main
    .type   main, %function
main:
    @ args = 0, pretend = 0, frame = 0
    @ frame_needed = 1, uses_anonymous_args = 0
    stmfd   sp!, {fp, lr}
    add     fp, sp, #4
    ldr     r0, .L2
    bl      printf
    mov     r0, r3
    ldmfd   sp!, {fp, pc}
.L3:
    .align  2
.L2:
    .word   .LC0
    .size   main, .-main
    .ident  "GCC: (Raspbian 4.9.2-10) 4.9.2"
    .section    .note.GNU-stack,"",%progbits

以下是我的C代碼:

// Hello World program in C

#include<stdio.h>

main()
{
    printf("Hello World");
}

使用GNU調試器,“gdb”!
gdb --args ./store01啟動GNU調試器。
它應該像控制台一樣。
您可以通過鍵入quit
但是當然你想逐步運行程序並檢查寄存器上下文。 所以輸入start ,跳轉到main()並跳過初始化的東西。
然后鍵入disassembledisas以顯示您正在運行的匯編程序。
現在每個鍵入stepi按照指令運行程序指令。
現在有趣的部分:輸入info registers r3並觀察輸出!
另一個奇妙的事情:你可以改變運行時的值:嘗試p $r0 = 2
那不是全部。
這是官方文檔: https//www.gnu.org/software/gdb/documentation/
一個好的,小的和有用的教程: http//thinkingeek.com/2013/01/12/arm-assembler-raspberry-pi-chapter-4

好吧,讓我們分解吧。

stmfd sp!, {fp, lr}

STMFD表示“存儲多個完全降序”。 本質上,它使用寄存器sp作為下行堆棧指針,並按順序將寄存器fplr放在堆棧上。 fp是幀指針, lr是鏈接寄存器(保存返回地址,后面很重要)。

add fp, sp, #4

將幀指針寄存器設置為等於sp + 4(指向剛存儲fp )。 這是沒有優化的編譯工件。

ldr r0, .L2

這是將存儲在地址.L2 (在本例中為.LC0的地址,字符串(well,char數組) "Hello World!\\000" )中存儲的32位值加載到寄存器r0

bl printf

通過在以null結尾的字符串"Hello World"上調用printf函數來組裝。 回想一下,指向這個數組的指針只是加載到r0 通常,GCC分別使用寄存器r0-r3作為函數的第一,第二,第三和第四個參數。 根據需要,其他參數存儲在堆棧中。

mov r0, r3

這是代碼中的錯誤的指示器,這個版本的GCC沒有捕獲。 基本上,您的函數返回一個類型(假設您從未指定為int ),但您從未指定返回值。 因此,返回值是r3發生的任何事情,這是未定義的。

ldmfd sp!, {fp, pc}

這與函數開頭編譯的stmfd指令相反。 但是不是加載到fp, lr ,而是加載到fp, pc 這導致lr的原始值直接移動到程序計數器pc pc是一個特殊的寄存器,它指向下一條執行的指令。 每次將pc設置為某個值時,CPU立即開始執行該值指向的代碼。 此屬性用於return調用例程,因為ARM指令集沒有顯式的ret操作。

暫無
暫無

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

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