① C編譯器一般包括匯編器嗎
樓主把概念搞混了,匯編器(比如MASM)全稱是匯編編譯器,用來編譯匯編語言的。我想在一般的程序中,是用來編譯內嵌的匯編碼的。
匯編語言的大部分命令都和機器碼一一對應,
而高級語言和匯編的偽指令是不和機器碼一一對應的
(也許高級語言一句會轉換為N句機器碼)。
因此從某種意義上說,匯編碼就相當於機器碼。
創造匯編只不過是看著舒服點而已,
要不然輸入的指令只能由0或1構成,
和這些東西打交道會多麻煩啊。
編譯器的作用是,將源文件(.c/.cpp/.pas等)轉換為目標代碼(.obj/.dcu等)。這是已經是二進制代碼了。
最後又連接器(Linker),將目標代碼連接起來,
這樣才形成了可執行文件
② 一般用什麼軟體來寫匯編程序
匯編語言(Assembly Language)是面向機器的程序設計語言。
在匯編語合中,用助記符(Memoni)代替操作碼,用地址符號(Symbol)或標號(Label)代替地址媽。這樣用符號代替機器語盲的二進制碼,就把機器語音變成了匯編語言。於是匯編語言亦稱為符號語言。
使用匯編語言編寫的程序,機器個能直接識別,要由一種程序將匯編語言翻譯成機器語言,這種起翻譯作用的程序叫匯編程序,匯編程序是系統軟體中語言處理系統軟體。匯編語言把匯編程序翻譯成機器語言的過程稱為f匯編。
匯編語言比機器語言易於讀寫、易於調試和修改,同時也具有機器語言執行速度快,占內存空間少等優點,但在編寫復雜程序時具有明顯的局限性,匯編語言依賴於具體的機型,不能通用,也不能在不同機型之間移植。
■對於不同型號的計算機,有著不同的結構的匯編語言
匯編語言由於採用了助記符號來編寫程序,比用機器語言的二進制代碼編程要方便些,在一定程度上簡化了編程過程。匯編語言的特點是用符號代替了機器指令代碼,而且助記符與指令代碼一一對應,基本保留了機器語言的靈活性。使用匯編語言能面向機器並較好地發揮機器的特性,得到質量較高的程序。
匯編語言是面向具體機型的,它離不開具體計算機的指令系統,因此,對於不同型號的計算機,有著不同的結構的匯編語言,而且,對於同一問題所編制的匯編語言程序在不同種類的計算機間是互不相通的。
匯編語言中由於使用了助記符號,用匯編語言編制的程序輸入計算機,計算機不能象用機器語言編寫的程序一樣直接識別和執行,必須通過預先放入計算機的"匯編程序"的加工和翻譯,才能變成能夠被計算機識別和處理的二進制代碼程序。用匯編語言等非機器語言書寫好的符號程序稱為源程序,運行時匯編程序要將源程序翻譯成目標程序。目標程序是機器語言程序,它一經被安置在內存的預定位置上,就能被計算機的CPU處理和執行。
匯編語言像機器指令一樣,是硬體操作的控制信息,因而仍然是面向機器的語言,使用起來還是比較繁瑣費時,通用性也差。但是,匯編語言用來編制系統軟體和過程式控制制軟體,其目標程序佔用內存空間少,運行速度快,有著高級語言不可替代的用途。
■html屬於匯編嗎?
不屬於匯編語言。它是Hypertext Markup Language的縮寫,用來編寫網頁的語言.通常一個網頁的網址最後面有.html或者.htm都是用這種語言編寫的.
另外,它一般用來編寫靜態網頁,現在最流行的動態語言有ASP,.NET和PHP等等.
③ 匯編器和鏈接器如何對段進行管理
編譯器將原代碼c或c++編譯成匯編asm文件,匯編器將asm文件匯編為目標文件obj(二進制文件),連接器將obj和lib等連接為最後的out文件(二進制)
④ [openharmony]liteos-a系統編譯之GN
在 文章 中已經分析openharmony的小型系統(liteos-a)編譯過程,最主要的就是調用gn/ninja/makefs三個命令最終生成可燒錄的鏡像文件
從前面文件可以看到hb build調用的gn命令參數如下
這里詳細分析一下gn工具在編譯過程中的使用
這里簡單介紹下GN工具的使用方法,gn語法可以參考 http://weharmonyos.com/openharmony/compile/gn/docs/
,已經熟悉的可以跳過
從上面圖中可以看到使用的命令類型為 gn gen <output_dir> [options] ,此命令就是為了將所有需要的BUILD.gn文件生成為*.ninja文件供ninja進行編譯; 可以通過 gn help gen 命令查看詳細的用法說明, 如下
下面重點說一下gn_cmd中的 [options]
liteos-a編譯系統的dotfile內容如下:
liteos-a是嵌入式系統,而編譯環境是linux系統,這就需要用到交叉編譯方式,這個就可以在環境配置中指定 target_os 、 target_cpu 、 board_cpu 等等信息
這些信息就是 buildconfig 參數指定的 BUILDCONFIG.gn 文件中配置的
除了以上信息,還配置了以下幾個重要信息
詳細信息可以查看 //build/lite/config/BUILDCONFIG.gn 文件內容
toolchain定義源碼編譯需要的工具,像編譯器、匯編器、連接器等等,一般在.gn所在目錄下有一個 toolchain 目錄,裡面的 BUILD.gn 定義詳細的編譯工具鏈信息
這里目錄結構如下:
從結構信息中可以看到定義了clang和gcc兩種工具鏈,通過變數 board_toolchain_type 來區分(此變數也是buildconfig中定義的),具體信息參見BUILD.gn文件內容,如下
在.gn文件所在目錄下的BUILD.gn就是入口,此文件做了以下幾個事情
這里重點說一下target為 ohos 的 group 如下:
這里也比較好理解,裡面就是讀取一個配置文件,幾級循環來處理配置文件中配置的內容。流程如下
到此就將此board下各模塊的依賴關系添加好了,然後 GN 會將依賴樹中所有的BUILD.gn生成對應的.ninja文件,並且在out的根目錄下生成下面幾個ninja的入口文件以及配置文件
⑤ win7下學習匯編語言,用什麼編譯器比較合適
win7有32位和64位之分:
1、如果是32位Win7,那麼任意一個編譯器都是可以的。
2、如果是64位Win7的話,那麼很多編譯器是無法正常運行的,必須選擇支持64位系統的編譯器。比如「匯編語言編譯器 v1.2 64位_官方版」就可以。
⑥ 匯編器和連接器區別
匯編器是把代碼翻譯成二進製程序
連接器是把程序和鏈接庫鏈接
⑦ 匯編編譯器和連接器是如何協同工作的
NO,I 't now .《lntel匯編程序設計》的作業題可以找的啊......
..................................................................................................................................................................................................................
⑧ 編譯軟體具體是什麼啊為屬於系統軟體啊
編譯軟體為匯編語言匯編器,例如C語言編譯、連接器等等。
一般來講,系統軟體包括操作系統和一系列基本的工具(比如編譯器,資料庫管理,存儲器格式化,文件系統管理,用戶身份驗證,驅動管理,網路連接等方面的工具),是支持計算機系統正常運行並實現用戶操作的那部分軟體。
有代表性的系統軟體:操作系統,語言處理程序(如編譯軟體),資料庫管理,輔助程序。
(8)編譯匯編器連接器擴展閱讀:
語言處理程序:
編譯軟體CPU執行每一條指令都只完成一項十分簡單的操作,一個系統軟體或應用軟體,要由成千上萬甚至上億條指令組合而成。直接用基本指令來編寫軟體,是一件極其繁重而艱難的工作。
計算機只能直接識別和執行機器語言,因此要計算機上運行高級語言程序就必須配備程序語言翻譯程序,翻譯程序本身是一組程序,不同的高級語言都有相應的翻譯程序。
語言處理程序如匯編語言匯編器,C語言編譯、連接器等。
為了提高效率,人們規定一套新的指令,稱為高級語言,其中每一條指令完成一項操作,這種操作相對於軟體總的功能而言是簡單而基本的,而相對於CPU的一眇操作而言又是復雜的。用這種高級語言來編寫程序(稱為源程序)就象用預制板代替磚塊來造房子,效率要高得多。
但CPU並不能直接執行這些新的指令,需要編寫一個軟體,專門用來將源程序中的每條指令翻譯成一系列CPU能接受的基本指令(也稱機器語言)使源程序轉化成能在計算機上運行的程序。完成這種翻譯的軟體稱為高級語言編譯軟體,通常把它們歸入系統軟體。
目前常用的高級語言有VB、C++、JAVA等,它們各有特點,分別適用於編寫某一類型的程序,它們都有各自的編譯軟體。
參考資料:網路——系統軟體
⑨ 匯編器和編譯器有什麼區別
匯編器(Assembler)是將匯編語言翻譯為機器語言的程序。一般而言,匯編生成的是目標代碼,需要經鏈接器(Linker)生成可執行代碼才可以執行。
匯編語言是一種以處理器指令系統為基礎的低級語言,採用助記符表達指令操作碼,採用標識符表示指令操作數。作為一門語言,對應於高級語言的編譯器,需要一個「匯編器」來把匯編語言原文件匯編成機器可執行的代碼。常用的高級語言編譯器有Microsoft公司的MASM系列和Borland公司的TASM系列編譯器,還有一些小公司推出的或者免費的匯編軟體包等。
編譯器就是將「一種語言(通常為高級語言)」翻譯為「另一種語言(通常為低級語言)」的程序。一個現代編譯器的主要工作流程:源代碼 (source code) → 預處理器 (preprocessor) → 編譯器 (compiler) → 目標代碼 (object code) → 鏈接器(Linker) → 可執行程序 (executables)
高級計算機語言便於人編寫,閱讀交流,維護。機器語言是計算機能直接解讀、運行的。編譯器將匯編或高級計算機語言源程序(Source program)作為輸入,翻譯成目標語言(Target language)機器代碼的等價程序。源代碼一般為高級語言 (High-level language), 如Pascal、C、C++、Java、漢語編程等或匯編語言,而目標則是機器語言的目標代碼(Object code),有時也稱作機器代碼(Machine code)。
對於C#、VB等高級語言而言,此時編譯器完成的功能是把源碼(SourceCode)編譯成通用中間語言(MSIL/CIL)的位元組碼(ByteCode)。最後運行的時候通過通用語言運行庫的轉換,編程最終可以被CPU直接計算的機器碼(NativeCode)
⑩ c語言中define的用法
C語言是計算機軟體領域非常經典的編程語言,unix、linux等眾多操作系統均是由C語言編寫而成。而在硬體控制、底層驅動等應用領域,C語言更是具有不可替代的作用。下面我就跟你們詳細介紹下c語言中define的用法,希望對你們有用。
c語言中define的用法如下:
#define是C語言中提供的宏定義命令,其主要目的是為程序員在編程時提供一定的方便,並能在一定程度上提高程序的運行效率,但學生在學習時往往不能 理解該命令的本質,總是在此處產生一些困惑,在編程時誤用該命令,使得程序的運行與預期的目的不一致,或者在讀別人寫的程序時,把運行結果理解錯誤,這對 C語言的學習很不利。
1. #define命令剖析
1.1 #define的概念
#define命令是C語言中的一個宏定義命令,它用來將一個標識符定義為一個字元串,該標識符被稱為宏名,被定義的字元串稱為替換文本。
該命令有兩種格式:一種是簡單的宏定義,另一種是帶參數的宏定義。
(1) 簡單的宏定義:
#define <宏名><字元串>
例: #define PI 3.1415926
(2) 帶參數的宏定義
#define <宏名> (<參數表>) <宏體>
例: #define A(x) x
一個標識符被宏定義後,該標識符便是一個宏名。這時,在程序中出現的是宏名,在該程序被編譯前,先將宏名用被定義的字元串替換,這稱為宏替換,替換後才進行編譯,宏替換是簡單的替換。
1.2 宏替換發生的時機
為了能夠真正理解#define的作用,讓我們來了解一下對C語言源程序的處理過程。當我們在一個集成的開發環境如Turbo C中將編寫好的源程序進行編譯時,實際經過了預處理、編譯、匯編和連接幾個過程,見圖1。
源程序預處理器修改後的源程序編譯器匯編程序匯編器可重定位的目標程序連接器可執行的目標程序圖1C語言的編譯過程
其中預處理器產生編譯器的輸出,它實現以下的功能:
(1) 文件包含
可以把源程序中的#include 擴展為文件正文,即把包含的.h文件找到並展開到#include 所在處。
(2) 條件編譯
預處理器根據#if和#ifdef等編譯命令及其後的條件,將源程序中的某部分包含進來或排除在外,通常把排除在外的語句轉換成空行。
(3) 宏展開
預處理器將源程序文件中出現的對宏的引用展開成相應的宏 定義,即本文所說的#define的功能,由預處理器來完成。
經過預處理器處理的源程序與之前的源程序有所有不同,在這個階段所進行的工作只是純粹的替換與展開,沒有任何計算功能,所以在學習#define命令時只要能真正理解這一點,這樣才不會對此命令引起誤解並誤用。
2#define使用中的常見問題解析
2.1 簡單宏定義使用中出現的問題
在簡單宏定義的使用中,當替換文本所表示的字元串為一個表達式時,容易引起誤解和誤用。如下例:
例1 #define N 2+2
void main()
{
int a=N*N;
printf(“%d”,a);
}
(1) 出現問題:在此程序中存在著宏定義命令,宏N代表的字元串是2+2,在程序中有對宏N的使用,一般同學在讀該程序時,容易產生的問題是先求解N為2+2=4,然後在程序中計算a時使用乘法,即N*N=4*4=16,其實該題的結果為8,為什麼結果有這么大的偏差?
(2)問題解析:如1節所述,宏展開是在預處理階段完成的,這個階段把替換文本只是看作一個字元串,並不會有任何的計算發生,在展開時是在宏N出現的地方 只是簡單地使用串2+2來代替N,並不會增添任何的符號,所以對該程序展開後的結果是a=2+2*2+2,計算後=8,這就是宏替換的實質,如何寫程序才 能完成結果為16的運算呢?
(3)解決辦法:將宏定義寫成如下形式
#define N (2+2)
這樣就可替換成(2+2)*(2+2)=16
2.2 帶參數的宏定義出現的問題
在帶參數的宏定義的使用中,極易引起誤解。例如我們需要做個宏替換能求任何數的平方,這就需要使用參數,以便在程序中用實際參數來替換宏定義中的參數。一般學生容易寫成如下形式:
#define area(x) x*x
這在使用中是很容易出現問題的,看如下的程序
void main()
{
int y=area(2+2);
printf(“%d”,y);
}
按理說給的參數是2+2,所得的結果應該為4*4=16,但是錯了,因為該程序的實際結果為8,仍然是沒能遵循純粹的簡單替換的規則,又是先計算再替換 了,在這道程序里,2+2即為area宏中的參數,應該由它來替換宏定義中的x,即替換成2+2*2+2=8了。那如果遵循(1)中的解決辦法,把2+2 括起來,即把宏體中的x括起來,是否可以呢?#define area(x) (x)*(x),對於area(2+2),替換為(2+2)*(2+2)=16,可以解決,但是對於area(2+2)/area(2+2)又會怎麼樣 呢,有的學生一看到這道題馬上給出結果,因為分子分母一樣,又錯了,還是忘了遵循先替換再計算的規則了,這道題替換後會變為 (2+2)*(2+2)/(2+2)*(2+2)即4*4/4*4按照乘除運算規則,結果為16/4*4=4*4=16,那應該怎麼呢?解決方法是在整個 宏體上再加一個括弧,即#define area(x) ((x)*(x)),不要覺得這沒必要,沒有它,是不行的。
要想能夠真正使用好宏定義,那麼在讀別人的程序時,一定要記住先將程序中對宏的使用全部替換成它所代表的字元串,不要自作主張地添加任何其他符號,完全展 開後再進行相應的計算,就不會寫錯運行結果。如果是自己編程使用宏替換,則在使用簡單宏定義時,當字元串中不只一個符號時,加上括弧表現出優先順序,如果是 帶參數的宏定義,則要給宏體中的每個參數加上括弧,並在整個宏體上再加一個括弧。看到這里,不禁要問,用宏定義這么麻煩,這么容易出錯,可不可以摒棄它, 那讓我們來看一下在C語言中用宏定義的好處吧。
3 宏定義的優點
(1) 方便程序的修改
使用簡單宏定義可用宏代替一個在程序中經常使用的常量,這樣在將該常量改變時,不用對整個程序進行修改,只修改宏定義的字元串即可,而且當常量比較長時, 我們可以用較短的有意義的標識符來寫程序,這樣更方便一些。我們所說的常量改變不是在程序運行期間改變,而是在編程期間的修改,舉一個大家比較熟悉的例 子,圓周率π是在數學上常用的一個值,有時我們會用3.14來表示,有時也會用3.1415926等,這要看計算所需要的精度,如果我們編制的一個程序中 要多次使用它,那麼需要確定一個數值,在本次運行中不改變,但也許後來發現程序所表現的精度有變化,需要改變它的值, 這就需要修改程序中所有的相關數值,這會給我們帶來一定的不便,但如果使用宏定義,使用一個標識符來代替,則在修改時只修改宏定義即可,還可以減少輸入 3.1415926這樣長的數值多次的情況,我們可以如此定義 #define pi 3.1415926,既減少了輸入又便於修改,何樂而不為呢?
(2) 提高程序的運行效率
使用帶參數的宏定義可完成函數調用的功能,又能減少系統開 銷,提高運行效率。正如C語言中所講,函數的使用可以使程序更加模塊化,便於組織,而且可重復利用,但在發生函數調用時,需要保留調用函數的現場,以便子 函數執行結束後能返回繼續執行,同樣在子函數執行完後要恢復調用函數的現場,這都需要一定的時間,如果子函數執行的操作比較多,這種轉換時間開銷可以忽 略,但如果子函數完成的功能比較少,甚至於只完成一點操作,如一個乘法語句的操作,則這部分轉換開銷就相對較大了,但使用帶參數的宏定義就不會出現這個問 題,因為它是在預處理階段即進行了宏展開,在執行時不需要轉換,即在當地執行。宏定義可完成簡單的操作,但復雜的操作還是要由函數調用來完成,而且宏定義 所佔用的目標代碼空間相對較大。所以在使用時要依據具體情況來決定是否使用宏定義。
形式參數不能用帶引號的字元串替換。
但是,如果在替換文本中,參數名以#作為前綴則結果將被擴展為 由 實際參數 替換 此實際參數的帶引號的字元串。
例如,可以將它與字元串連接運算結合起來編寫一個調試列印宏:
#define dprint(expr) printf(#expr “ = %\n”,expr)
使用語句 dprint(x/y);
調用宏時,該宏將被擴展為:printf(“x/y”“ = %\n”,x/y);
其中的字元串被連接起來了,這樣便等價於printf(“x/y = %\n”,x/y);
在實際參數中,每個雙引號 “ 將被替換為 \” ;反斜杠\將被替換為\\,因此替換後的字元串是合法的字元串常量。
預處理運算符 ## 為宏擴展提供了一種連接實際參數的手段。如果替換文本中的參數與 ## 相鄰,則該參數將被實際參數替換,##與前後的空白符將被刪除,並對替換後的結果重新掃描。
例如,下面定義的宏paste用於連接兩個參數
#define paste(front, back) front ## back
因此,宏調用past(name,1)的結果將建立記號name1.
c語言中沒有swap這個函數,C語言不支持重載,也沒有模版的概念,所以對於每一種類型,都要寫出相應的swap,如
intSwap (int *, int *);
longSwap (long *, long *);
stringSwap (char *, char *);
宏定義swap(t,x,y)以交換t類型的兩個參數(要使用程序塊結構)。
程序如下:
#include <iostream.h>
#define SWAP(t,x,y) \
{\
t temp = *y;\
*y = *x;\
*x = temp;\
}
main()
{
int a = 10, b = 5;
SWAP(int,&a,&b)
cout << a << endl << b<<endl;
}
用\換行,\的意思是說把下一行看作和這行是同一行.換行必須要反斜杠,而且\後面直接回車,不能有空格。