用C語言的思維寫彙編

2021-10-06 09:19:42 字數 3872 閱讀 7776

在c語言中:

;

//常量資料

;//函式

int main

在彙編中:

data segment

;//常量資料

data ends

code segment

assume cs:code,ds:data

main:

;//邏輯**和執行中變數資料

mov ax,

4c00h

int21h

;//函式

code ends

end main

c語言中:

const

int a=

12

在彙編中:

資料定義在data段。

假如要訪問data的資料:

data segment

a dw 12

data ends..

.mov ax,data

mov ds ax

mov ax,ds:

[a]

之後使用ds:[var_name]即可

void

main()

彙編寫法:

code segment

assume cs:code

main:

a dw 12

;//定義a變數 int a=12

b dw 23

;//定義b變數 int b=23

x dw 0

;//定義x變數 int x=0

mov si,offset a

mov di,offset b

mov bx,offset x

mov ax,cs:

[si]

add ax,cs:

[di]

mov cs:

[bx]

,ax ;

//x=a+b

mov ax,

4c00h;

//return 0

int21h

code ends

end main

完成函式任務需要注意的是堆疊進出的問題,注意兩個問題:(1)保留現場(2)返回修改資料

保留現場是因為我們在執行函式段的時候必然會對暫存器進行修改,而計算機的暫存器就這麼多,所以我們需要對執行函式之前的資料進行儲存現場。

傳參:

一般來說,我們會使用ax暫存器作為資料的返回和傳入,我們優先使用通用暫存器作為資料返回的載體。

返回用 ret 指令,相當於return的意思。

【例子】

假如我們現在要完成以下c**:

int

func

(int a,

int b)

void

main()

彙編**:

code segment

assume cs:code

main:

a dw 2

b dw 3

mov si,offset a

mov di,offset b

mov ax,cs:

[si]

;ax=a

mov dx,cs:

[di]

;dx=b

call func ;

//呼叫func函式

x db 0

;// int x=0

mov si,offset x

mov cs:

[si]

,ax ;

//x=func(a,b)

mov ax,

4c00h

int21h

;########### functions ################

func:

add ax,dx

retcode ends

end main

在彙編裡面,是不存在有無符號數的問題的

首先,我們假設在16位計算機上,我們定義乙個暫存器最大能承載的資料是:dw型別,而也就是ffff。此時的ffff他是乙個數,那你說這個是負數還是正數呢?

答案是你既可以把他看作正數也可以看作負數。

????(小朋友你是否有很多問號)

而你把他看成正數還是負數,取決於你當前的運算需求

比如說,現在我們要計算:-2+1=?(那這很明顯是有符號數的運算咯~)

那麼,你在彙編定義:

a dw -

2

檢視記憶體的資料是fffe

如果你把他和2相加,得到的資料是:ffff

也就是-1。

但你說,好,接下來,我把他看成無符號數來運算,那實際上直接拿的是ffff進行運算。

無論你是加還是減,乘還是除法,當前的這個數是正數還是負數,完全取決於你本身在腦子裡面定義的邏輯是:當前是有符號數的算術還是無符號數的算術。

要想保證我們得到的結果是正常的,就必須保證不要越位溢位了,例如,你說,現在我要拿乙個ffff+ffff,而且還是無符號數的運算,用add指令那肯定是算不出來的,因為你已經溢位了,除非你使用32位的運算指令。

牢牢記住彙編資料正負數的原則:正常計數,滿則清零,有無符號看需求

四則運算需要注意是之前說的有無符號的問題,需要根據我們的需求對數進行有無符號的定義。

除法

位元組除法指令:div cs:[si]

al=ax/cs:[si]

ah是餘數

字除法指令:div cs:[si]

ax=ax/cs:[si]

dx是餘數存放

需要注意的是,如果我們執行字除法指令,dx必須要先清零!!

乘法

位元組乘法指令:mul cs:[si]

ax=al*cs:[si]

字乘法指令:mul cs:[si]

dxax=ax * cs:[si]

這裡需要注意是乘除法的範圍問題,除法,我們可以想象,當al存放最大的無符號數是ff,也就是255,ah同理。

不要越界即可。

首先你需要明白,我們在面板裡面列印出來的字元只有在ascii表上的字元,假如我們需要列印某個數字,我們就需要實現逐位列印。

為什麼我們說進製轉換的題目「假」呢?

首先,無論我們在需求上怎麼要求進製轉換,存放在記憶體和暫存器的資料都是實實在在的真值。我們需要牢牢記住這樣乙個原則:存的是真值!(運算的也是真值)

我們經常遇到一些需求說要進行進製轉換,實際上,所謂的進製轉換是 「顯示出來」 的進製轉換,也就是我們肉眼所見的數字,他不是真的。

在c語言中,我們已經掌握了一些進製假轉換的演算法,我們只需要掌握的是:16進製制轉n進製,n進製轉16進製制。

為啥用16進製作為掌握的標準呢?

因為存的是真值,我們在記憶體裡面除錯看到的是16進製制的資料,所以說,方便拿16進製作為中間人。

還有需要注意的是,我們要做到的是顯示出:其他進製的數字,但因為在記憶體除錯,只有四個格仔,根本放不下這麼長的數,所以我們需要用列印字元的方法進行顯示。

用C語言寫《母牛的故事》

有一頭母牛,它每年年初生一頭小母牛。每頭小母牛從第四個年頭開始,每年年初也生一頭小母牛。請程式設計實現在第n年的時候,共有多少頭母牛?input 輸入資料由多個測試例項組成,每個測試例項佔一行,包括乙個整數n 0 output 對於每個測試例項,輸出在第n年的時候母牛的數量。每個輸出佔一行。samp...

用C語言寫PHP擴充套件

1 預定義 在home目錄,也可以其他任意目錄,寫乙個檔案,例如caleng module.def 內容是你希望定義的函式名以及引數 int a int x,int y string b string str,int n 2 到php原始碼目錄的ext目錄 cd usr local php 5.4....

用C語言寫PHP擴充套件

用c語言寫php擴充套件 1 預定義 在home目錄,也可以其他任意目錄,寫乙個檔案,例如caleng module.def 內容是你希望定義的函式名以及引數 int a int x,int y string b string str,int n 2 到php原始碼目錄的ext目錄 cd usr l...