彙編 巨集應該怎麼寫

2021-10-13 18:42:19 字數 3184 閱讀 2612

還記得c中的define嗎,巨集是乙個和差不多的東西。

c中的define可以替換掉一部分東西,然後在實際的實現中將define的別名換成實際內容,最後程式才能跑起來,這裡也一樣,我們可以定義乙個巨集,然後在程式設計中直接呼叫巨集,便於我們的程式設計,主要是減少**的長度。

要明白,在最後的計算機實現,其實還是將巨集進行了展開,和子程式不一樣,子程式才能真正減少行數。

這裡我們定義了乙個叫xyz的巨集,將z賦值為x*y。

首先要有macro和endm作為邊界,在第一行macro後面有一些引數,這些引數可以在巨集中直接使用。

如果不需要引數這部分直接空著就行。

這個引數很有意思,可以是各種各樣亂七八糟的東西,比如null、常數,暫存器、表示式、偽指令(甚至是偽指令的一部分,後面提到),就連其他巨集名都可以傳進來,有一點像函式指標那味。

另外形參和實參的個數也可以不相等。(實參是程式傳入的,表示真實存在的;形參則是我們在巨集中給的名字,只是乙個叫法)

多餘的實參會被忽略,多餘的形參被置為空。

在呼叫的過程中,我們直接使用:xyz al,bl,dl就行。

一般來說,只要巨集呼叫在巨集定義之前就行,但我們還是建議在最開始,也就是在資料段前面。

這裡介紹三個:"&"、"%"、"!"

這部分有一點奇怪,不過在高階語言中也有,雖然記不住哪種了……

&:表示連線。

leap	macro  cond,lab

j&cond lab

endm

然後我們這樣呼叫:leap z,there

在展開的過程中,會變成:jz there。其中there是乙個標號,表示跳轉的位置。

真就是各種s操作。

我們不是說過可以傳遞表示式嗎,如果是直接傳入:disp 2*11-8

我們其實傳入的是乙個字串,為了防止這種問題,我們採取加百分號的方式。

disp	macro  x

string db 『answer:』, 『&x』,『$』

endm

……disp %(2

*11-8

)

實際:string db 『answer:』,『14』,』$』

這裡注意,x前的&符號是需要有的,目的是替代後形成新的符號或字串

在c中printf有%d、%f,那麼我們就不能使用百分號了,為了防止彙編中的這個問題,有了"!"的存在,相當於轉義字元。(年紀大了,應該是沒叫錯吧)

disp !%(2* 11-8) 的展開就變成了 string db 『answer:』, 『%(2* 11-8)』, 『$』

我們可能會在巨集定義中使用標號,我們知道巨集的本質就是在實現的過程中用定義代替我們的巨集呼叫,另外我們也知道標號不能重複,重複必暴斃

那如果是在巨集中使用,我們有這樣的辦法:

在marco偽指令之後加上一句:local 標號名

一定在marco之後,另外一行可以加好幾個。

在實際生成機器指令的時候,機器會以??+0000、??+0001,一直到ffff來標號不同的標號。

不玩文字遊戲了,我們看乙個叫next的標號:

absol macro oper

local next

cmp oper,

0 jns next

neg oper

next:

endm

absol var

absol bx

實際上的是這樣的:

cmp var,

0jns ?

?0000

neg var

next0000:

cmp bx,

0jns ?

?0001

neg bx

next0001:

如果是local a,b,c 三個標號,實際展開:

??0000

??0001

??0002

??0003

??0004

??0005

……人類的本質不一定是復讀機,還可能是套娃。

我們在a程式中呼叫巨集b,巨集b呼叫巨集c,那麼我們是不可以在a中呼叫c的,因為我們c的定義是在b內部完成的,也就是:

b marco *

*c marco *

endm

endm

如果是將c定義在a中,那你隨意。

最後copy一下子程式和巨集的區分,看一下就行:

巨集指令與子程式的區別:程式中重複出現的程式段既可以用巨集指令,也可以用子程式(過程)來編寫,兩者都可以簡化源程式的編寫,而且都是一次編寫,可多次呼叫。但是它們是兩個完全不同的概念,它們之間有一些異同之處。

處理的時間不同:巨集呼叫是在源程式被彙編時由匯程式設計序處理的;而子程式呼叫是在程式執行期間由cpu直接執行的。

處理的方式不同:兩者都必須先定義後使用,但巨集呼叫是用巨集體替換巨集呼叫偽指令,實參代替形參,源程式被翻譯成目標**後巨集定義隨著消失;而子程式則沒有這樣的替換操作,是以call指令將控制權由呼叫者轉給子程式並執行。

引數處理不同:巨集呼叫是以實參代替形參,引數的形式不受限制,可以是任何合法字元;子程式的引數需要暫存器或儲存單元進行傳遞,而且需要附加的指令實現引數傳遞。

執行速度不同:子程式呼叫時需要執行call指令和ret指令,還要執行實現引數傳遞的附加指令,因而會比巨集的執行速度稍慢。

占用的儲存器空間大小不同:巨集指令在每次呼叫時都要展開,把巨集體中的程式段複製一遍,因而用巨集指令編寫的程式在目標**中會重複出現相同或相似的程式段,占用記憶體空間較大;而子程式是由call指令呼叫的,無論呼叫多少次,子程式的目標**只在程式**現一次,目標**相對較短。

彙編 重複彙編怎麼寫

當我們想生成一系列的相同或相近 我們就可以使用重複彙編的方式。結構 rept 整數表示式 重複體endm其中整數表示式的值為迴圈次數。比如我們需要設定乙個1 10的bd型別 x 0rept 10 x x 1 db x endm或者我們採取重複彙編將a到z填入陣列table中 char a table...

部落格應該怎麼寫

雖然我們大部分在機房都呆了一年了,但是還是很多人對於部落格還是望而生畏,不能說是應付差事,但是總有一點一些部落格就頭疼的感覺,更有甚者,冥思苦想,最終寫出來的總是不敬人意。今天 大話 基本上都要看完了,其實對於這本書還是深有感觸的,以 大話 為題,說說部落格我們應該怎麼寫。與其抱怨需求總是在變化,不...

投標方案應該怎麼寫?

我寫這個可不是為了傳授或布道哦,我寫過一些投標方案,但是總想聽聽大家是怎麼寫的,都注意些什麼。所以,兄弟我先扔塊磚,大夥兒有玉的砸過來 前面幾天在寫乙份投標方案。連續幾天搞到晚上10 00以後,週末還搞了個通宵,昨天去投了。總算乙個包袱卸了下來,結果怎麼樣也顧不上了,大家都說 盡人事,聽天命吧。呵呵...