欧美大屁股bbbbxxxx,狼人大香伊蕉国产www亚洲,男ji大巴进入女人的视频小说,男人把ji大巴放进女人免费视频,免费情侣作爱视频

歡迎來到入門教程網(wǎng)!

C語言

當(dāng)前位置:主頁 > 軟件編程 > C語言 >

簡單分析針對ARM平臺的C語言程序的編譯問題

來源:本站原創(chuàng)|時(shí)間:2020-01-10|欄目:C語言|點(diǎn)擊: 次

  我們知道在C語言編譯時(shí),有那么幾個(gè)常用的優(yōu)化編譯選項(xiàng),分別是-O0,-O1,-O2,-O3以及-Os。之前一直覺得既然是優(yōu)化選項(xiàng),頂多是優(yōu)化一下邏輯,提高一些效率或者減少一下程序大小而已。很少會(huì)覺得它們會(huì)影響程序的最終結(jié)果。直到最近在ARM平臺上發(fā)現(xiàn)一個(gè)程序里的一個(gè)bug,才覺得這些優(yōu)化選項(xiàng)有時(shí)候也沒那么智能?;蛘哒f針對ARM平臺,還沒有那么智能。
      首先看這么一段程序,此程序是我將問題簡單化的程序:

#include<stdio.h>
#include<string.h>

int main()
{
 char buffer[1024] = {0,1,2,3,4,5,6,7};
 int iTest = 0x12345678;
 int *p = (int *)(buffer + 7);
 memcpy(p, &iTest, sizeof(iTest));
 printf("%x\n", buffer[6]); 
 printf("%x\n", buffer[9]); 
 return 0;
}

乍看之下,覺得這個(gè)程序沒啥問題。然后我們將此程序文件名稱叫point.c。然后分別用交叉編譯鏈進(jìn)行如下編譯:

 arm-xxx-linux-gcc point.c -o point0 -O0
 arm-xxx-linux-gcc point.c -o point1 -O1
 arm-xxx-linux-gcc point.c -o point2 -O2

    最終再分別執(zhí)行三個(gè)程序,結(jié)果卻有點(diǎn)出人意料:

 ./point0
 6
 34
 ./point1
 34
 0
 ./point2
 6
 0

    只有在-O0,也就是沒有優(yōu)化的情況下,結(jié)果才和假想的一致。但是同樣的問題在x86平臺上卻沒有問題。
    于是我通過用以下命令,分別來生成不同優(yōu)化選項(xiàng)下的匯編代碼,來確定在ARM平臺上編譯到底出了什么問題。

 arm-xxx-linux-gcc point.c -o point0.s -O0 -S
 arm-xxx-linux-gcc point.c -o point1.s -O1 -S
 arm-xxx-linux-gcc point.c -o point2.s -O2 -S

    然后對比三個(gè)匯編的代碼,發(fā)現(xiàn)問題出在memcpy這句話上。
    在point0.s中,程序是老老實(shí)實(shí)的調(diào)用的memcpy,然后就將0x12345678老老實(shí)實(shí)按照字節(jié)一個(gè)個(gè)的放到了buffer+7的位置。
    而在point1.s中程序則是沒有調(diào)用memcpy,而是用的語句:
    str        r3, [sp, #7]
    而此時(shí)r3中存儲的就是0x12345678;而由于我采用的ARM平臺是32位的,此語句執(zhí)行時(shí),地址線應(yīng)該不會(huì)發(fā)生變化,所以最終的結(jié)果是buffer+4到buffer+7的數(shù)據(jù)被覆蓋了,而不是buffer+7到buffer+10的數(shù)據(jù)被修改。
    而在point2.s中,貌似又針對流水線進(jìn)行了優(yōu)化,程序執(zhí)行順序會(huì)有所變化,在對buffer部分位置賦初值的順序是在str  r3, [sp, #7]之后,所以buffer+6處的數(shù)據(jù)反而是正確的6。
    分析到這兒,也許有人會(huì)說寫個(gè)簡單的程序,都會(huì)因?yàn)榫幾g的優(yōu)化選項(xiàng)不同導(dǎo)致結(jié)果不同,那這memcpy是不是就不敢用了?
    其實(shí)一般只要有較好的編程習(xí)慣的話,都不會(huì)遇到此類問題,比如下面的程序:

#include<stdio.h>
#include<string.h>

int main()
{
 char buffer[1024] = {0,1,2,3,4,5,6,7};
 int iTest = 0x12345678;
 char *p = buffer + 7;
 memcpy(p, &iTest, sizeof(iTest));
 printf("%x\n", buffer[6]); 
 printf("%x\n", buffer[9]); 
 return 0;
}

    這段程序其實(shí)只是簡單的改變了p的類型,就能保證在各種優(yōu)化下,結(jié)果都一樣。可見好的編程習(xí)慣是有多么的重要。

上一篇:C++中的按位與&amp;、按位與或|、按位異或^運(yùn)算符詳解

欄    目:C語言

下一篇:C++語言編寫寫日志類

本文標(biāo)題:簡單分析針對ARM平臺的C語言程序的編譯問題

本文地址:http://mengdiqiu.com.cn/a1/Cyuyan/2597.html

網(wǎng)頁制作CMS教程網(wǎng)絡(luò)編程軟件編程腳本語言數(shù)據(jù)庫服務(wù)器

如果侵犯了您的權(quán)利,請與我們聯(lián)系,我們將在24小時(shí)內(nèi)進(jìn)行處理、任何非本站因素導(dǎo)致的法律后果,本站均不負(fù)任何責(zé)任。

聯(lián)系QQ:835971066 | 郵箱:835971066#qq.com(#換成@)

Copyright © 2002-2020 腳本教程網(wǎng) 版權(quán)所有