91欧美超碰AV自拍|国产成年人性爱视频免费看|亚洲 日韩 欧美一厂二区入|人人看人人爽人人操aV|丝袜美腿视频一区二区在线看|人人操人人爽人人爱|婷婷五月天超碰|97色色欧美亚州A√|另类A√无码精品一级av|欧美特级日韩特级

0
  • 聊天消息
  • 系統(tǒng)消息
  • 評(píng)論與回復(fù)
登錄后你可以
  • 下載海量資料
  • 學(xué)習(xí)在線課程
  • 觀看技術(shù)視頻
  • 寫(xiě)文章/發(fā)帖/加入社區(qū)
會(huì)員中心
創(chuàng)作中心

完善資料讓更多小伙伴認(rèn)識(shí)你,還能領(lǐng)取20積分哦,立即完善>

3天內(nèi)不再提示

嵌入式系統(tǒng)的編程中指針直接操作內(nèi)存的方法介紹

電子工程技術(shù) ? 來(lái)源:未知 ? 2019-11-26 11:01 ? 次閱讀
加入交流群
微信小助手二維碼

掃碼添加小助手

加入工程師交流群

數(shù)據(jù)指針

嵌入式系統(tǒng)編程中,常常要求在特定的內(nèi)存單元讀寫(xiě)內(nèi)容,匯編有對(duì)應(yīng)的MOV指令,而除C/C++以外的其它編程語(yǔ)言基本沒(méi)有直接訪問(wèn)絕對(duì)地址的能力。在嵌入式系統(tǒng)的實(shí)際調(diào)試中,多借助C語(yǔ)言指針?biāo)哂械膶?duì)絕對(duì)地址單元內(nèi)容的讀寫(xiě)能力。以指針直接操作內(nèi)存多發(fā)生在如下幾種情況:

(1) 某I/O芯片被定位在CPU的存儲(chǔ)空間而非I/O空間,而且寄存器對(duì)應(yīng)于某特定地址;

(2) 兩個(gè)CPU之間以雙端口RAM通信,CPU需要在雙端口RAM的特定單元(稱為mail box)書(shū)寫(xiě)內(nèi)容以在對(duì)方CPU產(chǎn)生中斷;

(3) 讀取在ROM或FLASH的特定單元所燒錄的漢字和英文字模。


譬如:

unsigned char *p = (unsigned char *)0xF000FF00;
*p="11";

以上程序的意義為在絕對(duì)地址0xF0000+0xFF00(80186使用16位段地址和16位偏移地址)寫(xiě)入11。

在使用絕對(duì)地址指針時(shí),要注意指針自增自減操作的結(jié)果取決于指針指向的數(shù)據(jù)類別。上例中p++后的結(jié)果是p= 0xF000FF01,若p指向int,即:

int *p = (int *)0xF000FF00;
p++(或++p)的結(jié)果等同于:p = p+sizeof(int),而p-(或-p)的結(jié)果是p = p-sizeof(int)。

記住:CPU以字節(jié)為單位編址,而C語(yǔ)言指針以指向的數(shù)據(jù)類型長(zhǎng)度作自增和自減。理解這一點(diǎn)對(duì)于以指針直接操作內(nèi)存是相當(dāng)重要的。

函數(shù)指針

首先要理解以下三個(gè)問(wèn)題:

(1)C語(yǔ)言中函數(shù)名直接對(duì)應(yīng)于函數(shù)生成的指令代碼在內(nèi)存中的地址,因此函數(shù)名可以直接賦給指向函數(shù)的指針;

(2)調(diào)用函數(shù)實(shí)際上等同于"調(diào)轉(zhuǎn)指令+參數(shù)傳遞處理+回歸位置入棧",本質(zhì)上最核心的操作是將函數(shù)生成的目標(biāo)代碼的首地址賦給CPU的PC寄存器;

(3)因?yàn)楹瘮?shù)調(diào)用的本質(zhì)是跳轉(zhuǎn)到某一個(gè)地址單元的code去執(zhí)行,所以可以"調(diào)用"一個(gè)根本就不存在的函數(shù)實(shí)體,暈?請(qǐng)往下看:

請(qǐng)拿出你可以獲得的任何一本大學(xué)《微型計(jì)算機(jī)原理》教材,書(shū)中講到,186 CPU啟動(dòng)后跳轉(zhuǎn)至絕對(duì)地址0xFFFF0(對(duì)應(yīng)C語(yǔ)言指針是0xF000FFF0,0xF000為段地址,0xFFF0為段內(nèi)偏移)執(zhí)行,請(qǐng)看下面的代碼:

typedef void (*lpFunction) ( ); /* 定義一個(gè)無(wú)參數(shù)、無(wú)返回類型的*/
/* 函數(shù)指針類型*/
lpFunction lpReset = (lpFunction)0xF000FFF0; /* 定義一個(gè)函數(shù)指針,指向*/
/* CPU啟動(dòng)后所執(zhí)行第一條指令的位置*/
lpReset(); /* 調(diào)用函數(shù)*/

在以上的程序中,我們根本沒(méi)有看到任何一個(gè)函數(shù)實(shí)體,但是我們卻執(zhí)行了這樣的函數(shù)調(diào)用:lpReset(),它實(shí)際上起到了"軟重啟"的作用,跳轉(zhuǎn)到CPU啟動(dòng)后第一條要執(zhí)行的指令的位置。

記?。汉瘮?shù)無(wú)它,唯指令集合耳;你可以調(diào)用一個(gè)沒(méi)有函數(shù)體的函數(shù),本質(zhì)上只是換一個(gè)地址開(kāi)始執(zhí)行指令!

數(shù)組vs.動(dòng)態(tài)申請(qǐng)

在嵌入式系統(tǒng)中動(dòng)態(tài)內(nèi)存申請(qǐng)存在比一般系統(tǒng)編程時(shí)更嚴(yán)格的要求,這是因?yàn)榍度胧较到y(tǒng)的內(nèi)存空間往往是十分有限的,不經(jīng)意的內(nèi)存泄露會(huì)很快導(dǎo)致系統(tǒng)的崩潰。

所以一定要保證你的malloc和free成對(duì)出現(xiàn),如果你寫(xiě)出這樣的一段程序:

char * function(void)
{
char *p;
p = (char *)malloc(…);
if(p==NULL)
…;
… /* 一系列針對(duì)p的操作*/
return p;
}

在某處調(diào)用function(),用完function中動(dòng)態(tài)申請(qǐng)的內(nèi)存后將其free,如下:

char *q = function();

free(q);

上述代碼明顯是不合理的,因?yàn)檫`反了malloc和free成對(duì)出現(xiàn)的原則,即"誰(shuí)申請(qǐng),就由誰(shuí)釋放"原則。不滿足這個(gè)原則,會(huì)導(dǎo)致代碼的耦合度增大,因?yàn)橛脩粼谡{(diào)用function函數(shù)時(shí)需要知道其內(nèi)部細(xì)節(jié)!

正確的做法是在調(diào)用處申請(qǐng)內(nèi)存,并傳入function函數(shù),如下:

char *p="malloc"(…);
if(p==NULL)
…;
function(p);

free(p);
p="NULL";

而函數(shù)function則接收參數(shù)p,如下:

void function(char *p)
{
… /* 一系列針對(duì)p的操作*/
}

基本上,動(dòng)態(tài)申請(qǐng)內(nèi)存方式可以用較大的數(shù)組替換。對(duì)于編程新手,筆者推薦你盡量采用數(shù)組!嵌入式系統(tǒng)可以以博大的胸襟接收瑕疵,而無(wú)法"海納"錯(cuò)誤。畢竟,以最笨的方式苦練神功的郭靖勝過(guò)機(jī)智聰明卻范政治錯(cuò)誤走反革命道路的楊康。

給出原則:

(1)盡可能的選用數(shù)組,數(shù)組不能越界訪問(wèn)(真理越過(guò)一步就是謬誤,數(shù)組越過(guò)界限就光榮地成全了一個(gè)混亂的嵌入式系統(tǒng));

(2)如果使用動(dòng)態(tài)申請(qǐng),則申請(qǐng)后一定要判斷是否申請(qǐng)成功了,并且malloc和free應(yīng)成對(duì)出現(xiàn)!


const在C++語(yǔ)言中則包含了更豐富的含義,而在C語(yǔ)言中僅意味著:"只能讀的普通變量",可以稱其為"不能改變的變量"(這個(gè)說(shuō)法似乎很拗口,但卻最準(zhǔn)確的表達(dá)了C語(yǔ)言中const的本質(zhì)),在編譯階段需要的常數(shù)仍然只能以#define宏定義!故在C語(yǔ)言中如下程序是非法的:

關(guān)鍵字const

const意味著"只讀"。區(qū)別如下代碼的功能非常重要,也是老生常談,如果你還不知道它們的區(qū)別,而且已經(jīng)在程序界摸爬滾打多年,那只能說(shuō)這是一個(gè)悲哀: const int a;
int const a;
const int *a;
int * const a;
int const * a const;
const int SIZE = 10;
char a[SIZE]; /* 非法:編譯階段不能用到變量*/

關(guān)鍵字volatile

volatile變量可能用于如下幾種情況:
(1) 并行設(shè)備的硬件寄存器(如:狀態(tài)寄存器,例中的代碼屬于此類);
(2) 一個(gè)中斷服務(wù)子程序中會(huì)訪問(wèn)到的非自動(dòng)變量(也就是全局變量);
(3) 多線程應(yīng)用中被幾個(gè)任務(wù)共享的變量。

聲明:本文內(nèi)容及配圖由入駐作者撰寫(xiě)或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀點(diǎn)僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場(chǎng)。文章及其配圖僅供工程師學(xué)習(xí)之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問(wèn)題,請(qǐng)聯(lián)系本站處理。 舉報(bào)投訴
  • 嵌入式系統(tǒng)
    +關(guān)注

    關(guān)注

    41

    文章

    3747

    瀏覽量

    133622
  • C語(yǔ)言
    +關(guān)注

    關(guān)注

    183

    文章

    7644

    瀏覽量

    145569

原文標(biāo)題:嵌入式C語(yǔ)言高手煉成之內(nèi)存操作篇

文章出處:【微信號(hào):EngicoolArabic,微信公眾號(hào):電子工程技術(shù)】歡迎添加關(guān)注!文章轉(zhuǎn)載請(qǐng)注明出處。

收藏 人收藏
加入交流群
微信小助手二維碼

掃碼添加小助手

加入工程師交流群

    評(píng)論

    相關(guān)推薦
    熱點(diǎn)推薦

    如何提升嵌入式編程能力?

    其他硬件的數(shù)據(jù)手冊(cè),了解其特性和編程接口。 6. 學(xué)習(xí)低級(jí)編程嵌入式編程常常需要直接與硬件交互,因此學(xué)習(xí)如何進(jìn)行低級(jí)
    發(fā)表于 06-21 10:01

    C語(yǔ)言嵌入式系統(tǒng)編程注意事項(xiàng)-內(nèi)存操作

    C語(yǔ)言嵌入式系統(tǒng)編程注意事項(xiàng)之內(nèi)存操作嵌入式系統(tǒng)編程
    發(fā)表于 01-04 07:31

    什么是嵌入式操作系統(tǒng)內(nèi)存管理技術(shù)?

    還是一個(gè)開(kāi)放性的操作系統(tǒng),這意味著幾乎所有的智能手機(jī)嵌入式操作系統(tǒng)都允許用戶安裝第三方程序。因此,在操作系統(tǒng)設(shè)計(jì)時(shí)還要綜合考慮編程的易用性及
    發(fā)表于 07-30 07:19

    【原創(chuàng)】聊一聊內(nèi)存指針操作

    作者:蔡琰老師(張飛實(shí)戰(zhàn)電子高級(jí)工程師)在嵌入式系統(tǒng)中,對(duì)內(nèi)存地址的操作是一個(gè)重要的方面,從廣義上講,嵌入式
    發(fā)表于 07-28 09:10

    指針直接操作內(nèi)存會(huì)發(fā)生哪幾種情況

    數(shù)據(jù)指針  在嵌入式系統(tǒng)編程中,常常要求在特定的內(nèi)存單元讀寫(xiě)內(nèi)容,匯編有對(duì)應(yīng)的MOV指令,而除C/C++以外的其它
    發(fā)表于 12-15 08:56

    分享一些嵌入式系統(tǒng)編程內(nèi)存操作相關(guān)的避坑指南

    嵌入式系統(tǒng)編程中,內(nèi)存操作是我們常用到的,但往往也是易錯(cuò)的地方,怎么避免呢,今天給大家分享一些相關(guān)的避坑指南。數(shù)據(jù)
    發(fā)表于 12-17 07:18

    嵌入式操作系統(tǒng)Linux 中的串口應(yīng)用編程

    針對(duì)嵌入式Linux操作系統(tǒng)的特點(diǎn),分析在該系統(tǒng)下串行通信口編程控制的方法,總結(jié)程序設(shè)計(jì)的步驟; 在嵌入
    發(fā)表于 05-14 14:34 ?28次下載

    嵌入式系統(tǒng)內(nèi)存管理方案研究

    摘要:嵌入式系統(tǒng)內(nèi)存管理機(jī)制必須滿足實(shí)時(shí)性和可靠性的要求。本文以開(kāi)源的的操作系統(tǒng)RTEMS為例,介紹
    發(fā)表于 05-24 23:57 ?1550次閱讀
    <b class='flag-5'>嵌入式</b><b class='flag-5'>系統(tǒng)</b><b class='flag-5'>內(nèi)存</b>管理方案研究

    嵌入式系統(tǒng)編程之內(nèi)存操作學(xué)習(xí)

    嵌入式系統(tǒng)編程之內(nèi)存操作學(xué)習(xí) 1.數(shù)據(jù)指針嵌入式系統(tǒng)
    發(fā)表于 09-08 18:11 ?669次閱讀

    嵌入式操作系統(tǒng)FreeRTOS內(nèi)存如何管理和堆

    嵌入式操作系統(tǒng)FreeRTOS內(nèi)存管理和堆
    的頭像 發(fā)表于 01-10 15:17 ?6016次閱讀
    <b class='flag-5'>嵌入式</b><b class='flag-5'>操作系統(tǒng)</b>FreeRTOS<b class='flag-5'>內(nèi)存</b>如何管理和堆

    嵌入式操作系統(tǒng)如何應(yīng)用_嵌入式操作系統(tǒng)的組成

    本文首先介紹了入操作系統(tǒng)的特點(diǎn),其次闡述了嵌入式操作系統(tǒng)的應(yīng)用,最后介紹
    發(fā)表于 09-01 16:36 ?4013次閱讀

    嵌入式系統(tǒng)裸機(jī)編程內(nèi)存管理簡(jiǎn)介

    ? 在嵌入式裸機(jī)編程中,作為一名初級(jí)的CODER。經(jīng)常要與CPU、內(nèi)存等打交道。CPU作為系統(tǒng)的動(dòng)力源,其重要程度不言而喻。 ? 但是,在裸機(jī)編程
    的頭像 發(fā)表于 12-28 09:44 ?3932次閱讀
    <b class='flag-5'>嵌入式</b><b class='flag-5'>系統(tǒng)</b>裸機(jī)<b class='flag-5'>編程</b>的<b class='flag-5'>內(nèi)存</b>管理簡(jiǎn)介

    嵌入式系統(tǒng)內(nèi)存指針操作

    到處理器的內(nèi)存空間中。在x86系統(tǒng)中,分為內(nèi)存和I/O映射兩種內(nèi)存;在ARM體系中,全部的地址都在32位的內(nèi)存空間中,所有的
    的頭像 發(fā)表于 08-27 11:33 ?6997次閱讀

    淺談嵌入式系統(tǒng)裸機(jī)編程內(nèi)存管理

     malloc和free在PC編程中是很好用的一種內(nèi)存分配手段。但是,其在嵌入式中,就未必好用了。由于嵌入式裸機(jī)編程中,無(wú)MMU,即
    發(fā)表于 09-15 10:38 ?2068次閱讀

    嵌入式C語(yǔ)言高手煉成之內(nèi)存操作

    嵌入式系統(tǒng)編程中,常常要求在特定的內(nèi)存單元讀寫(xiě)內(nèi)容,匯編有對(duì)應(yīng)的MOV指令,而除C/C++以外的其它編程語(yǔ)言基本沒(méi)有
    的頭像 發(fā)表于 12-11 17:20 ?1235次閱讀