汇编语言开头写C清零是为啥,这个汇编语言代码是什么意思?
讓我們分解一下:
.file "delta.c"
編譯器使用它來告訴您程序集來自的源文件.這對匯編程序來說意義不大.
.section .rodata
這將開始一個新的部分. “rodata”是“只讀數(shù)據(jù)”部分的名稱.本節(jié)最終將數(shù)據(jù)寫入可執(zhí)行文件,該數(shù)據(jù)庫將內(nèi)存映射為只讀數(shù)據(jù).可執(zhí)行映像的所有“.rodata”頁面最終都被所有進程共享
加載圖像.
通常,源代碼中的任何“編譯時常量”都無法優(yōu)化到匯編內(nèi)部函數(shù)中,最終將存儲在“只讀數(shù)據(jù)部分”中.
.LC0:
.string "%d"
.LC0“部分是一個標簽.它提供了一個符號名稱,它引用文件中后面出現(xiàn)的字節(jié).在這種情況下,”LC0“表示字符串”%d“.GNU匯編程序使用標記開頭的約定帶有“L”的被認為是“本地標簽”.這具有技術含義,對編寫編譯器和鏈接器的人來說非常有趣.在這種情況下,編譯器使用它來引用特定目標文件專用的符號.在這種情況下,它表示一個字符串常量.
.text
這將開始一個新的部分. “text”部分是存儲可執(zhí)行代碼的目標文件中的部分.
.globl main
“.global”指令告訴匯編器將其后面的標簽添加到生成的目標文件“導出”的標簽列表中.這基本上意味著“這是一個應該對鏈接器可見的符號”.例如,“C”中的“非靜態(tài)”函數(shù)可以由聲明(或包括)兼容函數(shù)原型的任何c文件調(diào)用.這就是為什么你可以#include stdio.h然后調(diào)用printf.編譯任何非靜態(tài)C函數(shù)時,編譯器會生成聲明指向函數(shù)開頭的全局標簽的程序集.將此與不應鏈接的內(nèi)容(如字符串文字)進行對比.目標文件中的匯編代碼仍然需要一個標簽來引用文字數(shù)據(jù).那些是“本地”符號.
.type main, @function
我不確定GAS(gnu匯編程序)如何處理“.type”指令.但是,這指示匯編程序標簽“main”是指可執(zhí)行代碼,而不是數(shù)據(jù).
main:
這定義了“main”函數(shù)的入口點.
.LFB0:
這是一個“本地標簽”,指的是函數(shù)的開頭.
.cfi_startproc
這是一個“調(diào)用幀信息”指令.它指示匯編程序發(fā)出矮調(diào)格式的調(diào)試信息.
pushl %ebp
這是匯編代碼中函數(shù)“序言”的標準部分.它保存了“ebp”寄存器的當前值. “ebp”或“base”寄存器用于在函數(shù)內(nèi)存儲堆棧幀的“基礎”. “esp”(“堆棧指針”)寄存器可以在函數(shù)內(nèi)調(diào)用函數(shù)時更改,而“ebp”保持固定.始終可以相對于“ebp”訪問函數(shù)的任何參數(shù).通過ABI調(diào)用約定,在函數(shù)可以修改EBP寄存器之前,它必須保存它,以便在函數(shù)返回之前恢復原始值.
.cfi_def_cfa_offset 8
.cfi_offset 5, -8
我沒有詳細研究過這些,但我相信它們與DWARF調(diào)試信息有關.
movl %esp, %ebp
GAS使用AT& T語法,這是英特爾手冊使用的語法.這意味著“設置ebp等于esp”.這基本上為函數(shù)的其余部分建立了“基指針”.
.cfi_def_cfa_register 5
andl $-16, %esp
subl $32, %esp
這也是該功能的epilouge的一部分.這會對齊堆棧指針,然后從中減去足夠的空間來容納函數(shù)的所有本地.
movl $4, 28(%esp)
這將32位整數(shù)常量4加載到堆棧幀的插槽中.
movl $.LC0, %eax
這會將上面定義的“%d”字符串常量加載到eax中.
movl 28(%esp), %edx
這將堆棧中偏移量28中存儲的值“4”加載到edx.有可能你的代碼是在關閉優(yōu)化的情況下編譯的.
movl %edx, 4(%esp)
然后,將值4移動到堆棧上,在調(diào)用printf時需要的位置.
movl %eax, (%esp)
這會將字符串“%d”加載到調(diào)用printf時所需的堆棧上的位置.
call printf
這稱為printf.
movl $0, %eax
這將eax設置為0.鑒于下一條指令是“l(fā)eave”和“ret”,這相當于C代碼中的“return 0”. EAX寄存器用于保存函數(shù)的返回值.
leave
該指令清除呼叫幀.它將ESP設置回EBP,然后從修改后的堆棧指針中彈出EBP.像下一條指令一樣,這是函數(shù)結尾的一部分.
.cfi_restore 5
.cfi_def_cfa 4, 4
這是更多DWARF的東西
ret
這是實際的返回指令.它從功能中返回
.cfi_endproc
.LFE0:
.size main, .-main
.ident "GCC: (Ubuntu/Linaro 4.6.3-1ubuntu5) 4.6.3"
.section .note.GNU-stack,"",@progbits
總結
以上是生活随笔為你收集整理的汇编语言开头写C清零是为啥,这个汇编语言代码是什么意思?的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 巧用python求解逻辑题,特简单!
- 下一篇: 【整理】详解嵌入式片上资源之SDRAM内