《電子技術(shù)應(yīng)用》
您所在的位置:首頁 > 模擬設(shè)計 > 業(yè)界動態(tài) > 飛思卡爾hcs08 c語言之混和編程

飛思卡爾hcs08 c語言之混和編程

2017-07-23
關(guān)鍵詞: 匯編語言

混和編程

1)內(nèi)嵌匯編

HCS08 C 語言提供一個很有用的功能,內(nèi)嵌匯編。凡是C語言程序段能出現(xiàn)的地方匯編語言源程序都可以出現(xiàn),但是匯編語言源程序必需位于一個C語言函數(shù)中。

語法格式

1) "asm" <匯編指令> ";" ["/*" 注釋 "*/"]

雙引號中的內(nèi)容為關(guān)鍵字,方括號中的內(nèi)容為可選項。

例如:

asm sta COPCTL;   /* 喂狗 */

2) "asm" "{"

<匯編指令 1> [";" 注釋]

<匯編指令 2> [";" 注釋]

"}"

要求:大括號內(nèi)每條匯編指令占一行;標(biāo)號以“:”結(jié)尾占一行;注釋以“;”開始;可以用變量名訪問全局變量和C 函數(shù)中的局部變量。匯編語言結(jié)束前要保證堆棧內(nèi)容與匯編開始前一致。

例如:用內(nèi)嵌匯編方法實現(xiàn)統(tǒng)計字符串中字符的個數(shù)。

int strlen (char *str)

/*** 'str' 參數(shù)由堆棧傳遞. 函數(shù)返回字符串'str'的長度

假定字符串的長度小于256!

*/

{

asm {

LDHX str      ; 裝入指針

CLRA           ; 初始化計數(shù)器

BRA test      ; 跳到test

loop:

AIX #1        ; 指針加1

INCA          ; 計數(shù)器加1

test:

TST 0,X      ; 字符串是否結(jié)束?

BNE loop     ; 下一字符

CLRX          ; 返回值在 X:A(參見后文)

};

/* 這里可以繼續(xù)寫 C 語言程序段 */

}

2)混和調(diào)用

混和調(diào)用指的是C語言函數(shù)調(diào)用匯編語言函數(shù)和匯編語言函數(shù)調(diào)用C語言函數(shù)。實現(xiàn)混和調(diào)用要解決兩個問題1:常量和變量的相互訪問;2調(diào)用協(xié)議

1常量和變量的相互訪問

C 語言函數(shù)訪問匯編語言常量、變量

在匯編語言源程序中采用匯編語法定義變量和常量;在C語言中把這些變量、常量聲明為外部常量變量,即可以用變量、常量名來訪問。匯編器和編譯器敏感段名的大小寫。

例如:

匯編源程序中

XDEF ASMData, ASMConst ;聲明 ASMData, ASMConst 可以在模塊外訪問

MyData: SECTION

ASMData: DS.W 1 ; 定義變量

MyConst: SECTION

ASMConst: DC.W $44A6 ; 定義常量

在 C 語言源程序中

#pragma DATA_SEG MyData /* 定義變量段 */

extern int ASMData; /* 變量 ASMData 是外部模塊聲明的 */

#pragma DATA_SEG DEFAULT /* 返回默認(rèn)變量段 */

#pragma CONST_SEG MyConst /* 定義常數(shù)段 */

extern const int ASMConst; /* 常量 ASMConst 是外部模塊聲明的*/

#pragma CONST_SEG DEFAULT /*返回默認(rèn)常數(shù)段   */

匯編語言訪問C語言變量、常量

在C語言中用標(biāo)準(zhǔn)格式定義常量、變量,在匯編語言中聲明這些常量變量是外部定義即可。

例如:

在C語言源文件中:

unsigned int CData; /* 定義變量 */

unsigned const int CConst; /* 定義常量 */

在匯編語言源文件中:

XREF CData ; 外部聲明的變量

XREF CConst; 外部聲明的常量

使用:

LDD CConst

STD CData

2)調(diào)用協(xié)議

調(diào)用協(xié)議,即函數(shù)參數(shù)傳遞和返回值的協(xié)議。對于HC08和HCS08調(diào)用協(xié)議是不同的。

HC08 參數(shù)傳遞:調(diào)用者函數(shù)把所需參數(shù)從左到右依次入棧,調(diào)用結(jié)束后由調(diào)用者函數(shù)從堆棧中清除傳遞的參數(shù)。在函數(shù)傳遞的是值參數(shù)的情況下,如果最后一個參數(shù)長度為2字節(jié),則用X:A寄存器對傳遞;如果最后一個參數(shù)長度為1字節(jié)且倒數(shù)第2個參數(shù)長度超過1字節(jié),則最后一個參數(shù)用寄存器A傳遞;如果最后一個參數(shù)長度為1字節(jié)且倒數(shù)第2個參數(shù)長度也是1字節(jié),則最后一個參數(shù)用寄存器X傳遞,倒數(shù)第2個參數(shù)用寄存器A傳遞;

HCS08返回值:函數(shù)返回值總是在寄存器中,根據(jù)返回值的類型不同,而采用不同的寄存器

返回值類型

   

寄存器

   

char (signed 或 unsigned)

   

A

   

int (signed 或 unsigned)

   

H:X

   

pointers/arrays(指針/數(shù)組)

   

H:X

   

function pointers(函數(shù)指針)

   

H:X

   

如果返回值的長度超過2字節(jié),則在H:X存放返回值的地址。

例如:寫一段C語言源程序,然后把它編譯為匯編語言,觀察調(diào)用規(guī)則

#include /* 為了包含中斷允許宏定義*/

#include

unsigned char r;

unsigned char f1(unsigned char v1,unsigned char v2,unsigned char v3,unsigned char v4) {

    v1+=1;

     v2+=1;

     v3+=1;

     v4+=1;

     return(v4);

}

void f0(void) {

        r=f1(4,9,6,3);

    }

void main(void) {

   EnableInterrupts; /*中斷允許 */

               f0();

   for(;;) {

     __RESET_WATCHDOG(); /* 喂狗 */

   }  

}

在C語言源程序中f0函數(shù)調(diào)用f1函數(shù),傳遞參數(shù)并有返回值

函數(shù)f1編譯后的匯編語言

PSHA        ; 有參數(shù)用X、A傳遞,入棧保存防止破壞

PSHX

     TSX          ; X=SP+1

     INC    5,X   ; v1+=1,參數(shù)v1在sp+6處

     INC    4,X   ; v2+=1; 參數(shù)v2在sp+5處

     INC    1,X   ; v3+=1; 參數(shù)v3在A中,被本函數(shù)入棧

    INC    ,X    ; v4+=1; 參數(shù)v4在X中,被本函數(shù)入棧

     LDA    ,X    ; return(v4);返回值在A中

     AIS    #2    ; 調(diào)整堆棧指針,指向返回地址

     RTS    ; 返回f0函數(shù)

函數(shù)f0編譯后的匯編語言

     LDA    #4

     PSHA       ; 參數(shù)v1入棧

     LDA    #9

     PSHA       ; 參數(shù)v2入棧

     LDA    #6   ; 參數(shù)v3用A傳遞

     LDX    #3   ; 參數(shù)v4用X傳遞

     BSR    f1   ; 調(diào)用函數(shù)f1

     AIS    #2   ; 清除傳遞的參數(shù)

     STA    r    ; 保存返回值

     RTS        ; 返回main函數(shù)

Main函數(shù)編譯后的匯編語言

CLI   

BSR    f0

L3:     

STA    _COPCTL

BRA    L3

只要遵循以上調(diào)用規(guī)則,就可以實現(xiàn)用C函數(shù)和匯編函數(shù)的相互調(diào)用。調(diào)用時使用對方定義的函數(shù)名。

16.2.5啟動代碼

在啟動main函數(shù)之前HCS08 C 語言會自動運行一段啟動代碼,進(jìn)行硬件初始化和建立C語言的運行環(huán)境。起動代碼一般由編譯器自動生成,也可以由用戶自寫的啟動代碼替代自動生成的啟動代碼。啟動代碼的名字為start08.c,它的主要工作是:

l          禁止中斷

l          從ROM到RAM復(fù)制并初始化數(shù)據(jù)

l          未初始化的數(shù)據(jù)區(qū)域清零

l          為堆棧分配并初始化堆棧

l          如果用到堆,創(chuàng)建并初始化堆

l          允許中斷

l          調(diào)用main()函數(shù)

分類:


本站內(nèi)容除特別聲明的原創(chuàng)文章之外,轉(zhuǎn)載內(nèi)容只為傳遞更多信息,并不代表本網(wǎng)站贊同其觀點。轉(zhuǎn)載的所有的文章、圖片、音/視頻文件等資料的版權(quán)歸版權(quán)所有權(quán)人所有。本站采用的非本站原創(chuàng)文章及圖片等內(nèi)容無法一一聯(lián)系確認(rèn)版權(quán)者。如涉及作品內(nèi)容、版權(quán)和其它問題,請及時通過電子郵件或電話通知我們,以便迅速采取適當(dāng)措施,避免給雙方造成不必要的經(jīng)濟(jì)損失。聯(lián)系電話:010-82306118;郵箱:aet@chinaaet.com。