這是一個簡單的 C 語言程式。
char a;
void main(){};
它導致這個程式集開始生成
.text
.globl a
.bss
.type a, @object
.size a, 1
所以我想知道如何解釋上述內容
所以我看到.text我相信這只是符號.,text意味著代碼部分的開始而且你看到.global了所以我相信我的變數在此之后開始將是全域變數或函式等,或者我是否需要撰寫部分名稱,即.text就在所有變數和函式之前?這是問題
然后你.bss現在看到.,bss所有未初始化的變數和函式都被宣告了
最后我看到類似于我的 C 程式有一個名為的全域變數的char a
東西
.type a, @object
所以 .type 告訴它是什么所以我假設它的物件型別與@和objectin 中提到的一樣.type a,@object
所以現在大小是 1 個字符。所以這條線
.size a, 1
所以我假設如果我有全球int a;那么那將是
.size a,4
char 是 1 個位元組 int 是 4 個位元組
然后繼續
我有
a:
所以前幾行變成如下
假設這是代碼 1
# my comment 1
# my comment 2
.text
.globl a
.bss
.type a, @object
.size a, 1
a:
所以問題是為什么 a: 在底部
如果我這樣做怎么辦
這是代碼 2
a:
.text
.globl a
.bss
.type a, @object
.size a, 1
所以我想知道是code 1和code 2一樣的嗎?宣告或定義a:出現在第一個和第二個code 2
所以從上面我a的是.text和.global和是@object,.bss是1個位元組。這是很多代碼來定義一個 char 變數。那么理解正確嗎???我應該懷疑嗎.typesize
further moving on, now it turn of a global main which is in .text section plus .global
so I see
.zero 1
.text
.globl main
.type main, @function
main:
so I really dont want to care about .zero 1 line but if I am wrong not to care then tell me the use of it. so again have my gcc place main in .zero (some section???) and .text section plus .global code section and the type is @function so now I know type come after , as in .type main,@function and
in .type a, @object
then I encounter complete BS, searching for .LFB0: brought zero google search results
is .LFB0: a some section of program that my x86-64 processor can run
and .cfi_startproc is eh_frame so I read .eh_frame is a section that lives in the loaded part of the program. so I like to know if I am coding in assembly can I ignore .cfi_startproc line. but What is the point of this. does this mean after this everything is loaded in memory or registers and and is .ehframe
main:
.LFB0:
.cfi_startproc
endbr64
pushq %rbp #
.cfi_def_cfa_offset 16
.cfi_offset 6, -16
movq %rsp, %rbp #,
.cfi_def_cfa_register 6
so if I am making a simple assembly program simlar to above C program in assembly do I need to code from .LFB0: to movq %rsp, %rbp #,\n.cfi_def_cfa_register 6 if not needed then I can assume my program will become
.text
.globl a
.bss
.type a, @object
.size a, 1
a:
.zero 1
.text
.globl main
.type main, @function
main:
.cfi_startproc
pushq %rbp
movq %rsp, %rbp
nop
popq %rbp
ret
.cfi_endproc
so my full program becomes above, how to compile this with nasm can any one please tell I believe I have to save it with .s or .S extension which one s small or large S? I am coding in Ubuntu
This is gcc generated code
.file "test.c"
# GNU C17 (Ubuntu 11.2.0-7ubuntu2) version 11.2.0 (x86_64-linux-gnu)
# compiled by GNU C version 11.2.0, GMP version 6.2.1, MPFR version 4.1.0, MPC version 1.2.0, isl version isl-0.24-GMP
# GGC heuristics: --param ggc-min-expand=100 --param ggc-min-heapsize=131072
# options passed: -mtune=generic -march=x86-64 -fasynchronous-unwind-tables -fstack-protector-strong -fstack-clash-protection -fcf-protection
.text
.globl a
.bss
.type a, @object
.size a, 1
a:
.zero 1
.text
.globl main
.type main, @function
main:
.LFB0:
.cfi_startproc
endbr64
pushq %rbp #
.cfi_def_cfa_offset 16
.cfi_offset 6, -16
movq %rsp, %rbp #,
.cfi_def_cfa_register 6
# test.c:2: void main(){};
nop
popq %rbp #
.cfi_def_cfa 7, 8
ret
.cfi_endproc
.LFE0:
.size main, .-main
.ident "GCC: (Ubuntu 11.2.0-7ubuntu2) 11.2.0"
.section .note.GNU-stack,"",@progbits
.section .note.gnu.property,"a"
.align 8
.long 1f - 0f
.long 4f - 1f
.long 5
0:
.string "GNU"
1:
.align 8
.long 0xc0000002
.long 3f - 2f
2:
.long 0x3
3:
.align 8
4:
uj5u.com熱心網友回復:
.text是一個指令,它告訴匯編器開始一個程式代碼段(程式的“文本”段,一個只讀的可執行段,主要包含要執行的指令)。之所以在這里,是因為沒有優化的 GCC 總是將 a.text放在檔案的頂部,即使它即將切換到另一個部分(就像.bss在這種情況下),然后又回到.text它準備好向該部分發出一些位元組時(在你的情況下) , 的定義main)。不過,GCC 在發出任何 asm 之前仍然會決議整個編譯單元;它不僅僅是一次編譯一個全域變數/函式。
.globl a是一個指令,它告訴匯編器這a是一個“全域”符號,因此它的定義應該作為聯結器鏈接的外部符號列出。
.bss是一個指令,它告訴匯編器啟動“塊起始符號”部分(該部分將包含初始化為零的資料,或者在某些系統上,大多數是較舊的系統,未初始化)。
.type a @object并且.size a, 1是描述名為 的物件的型別和大小的指令a。匯編器將此資訊添加到符號表或它輸出的目標檔案中的其他資訊中。除錯器了解物件的型別很有用。
a:是標簽。它用于定義符號。當匯編器讀取匯編時,它會計算當前生成的部分中的位元組數。每個資料宣告或指令占用一些位元組,匯編器會計算這些位元組。當它看到一個標簽時,它將標簽與當前計數相關聯。(這通常稱為程式計數器,即使它正在計算資料位元組。)當匯編器將有關資訊寫入a符號表時,它將包括從節開頭開始的位元組數。當程式加載到記憶體中時,這個偏移量用于計算物件a在記憶體中的地址。
所以問題是為什么 a: 在底部
a:必須在之后,.bss因為a將被放入匯編器當前正在處理的部分中,因此需要在宣告標簽之前將其設定為所需的部分。相對于其他指令的位置a可能是靈活的,因此重新排序它們不會有任何后果。
所以我想知道代碼 1 和代碼 2 是否相同?
不,a:必須出現在后面,.bss以便將其放入正確的部分。
.zero 1表示在當前部分發出 1 個零位元組。像(幾乎?)GCC 使用的所有指令一樣,它在 GNU 匯編器手冊中有很好的記錄:https ://sourceware.org/binutils/docs/as/Zero.html
所以再次讓我的 gcc
main在.zero
不,.text開始(或切換回)代碼部分,因此main將在代碼部分中。
是 .LFB0:我的 x86-64 處理器可以運行的一段程式
任何以冒號結尾的都是標簽。.LFB0是編譯器在需要它作為跳轉或分支目標時使用的本地標簽。
所以我想知道我是否在匯編中編碼可以忽略
.cfi_startproc行。
在為沒有例外處理和相關功能的簡單函式撰寫程式集時,您可以忽略 .cfi_startproc 和其他生成該.eh_frame部分中的元資料的呼叫幀資訊指令。(它沒有被執行,它只是作為例外處理程式和除錯器讀取的檔案中的資料。)
……如果不需要,那么我可以假設我的程式將變成……
If you are omitting some of the .cfi… directives, I would omit all of them, unless you look into what they do and determine which ones can be omitted selectively.
I believe I have to save it with .s or .S extension which one s small or large S?
With GCC and Clang, assembly files ending in .S are processed by the “preprocessor” before assembly, and assembly files ending in .s are not. This is the preprocessor familiar from C, with #define, #if, and other directives. Other tools may not do this. If you are not using preprocessor features, it generally does not matter whether you use .s or .S.
轉載請註明出處,本文鏈接:https://www.uj5u.com/shujuku/437342.html
