日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

VS2005混合编译ARM汇编代码

發布時間:2023/12/9 编程问答 22 豆豆
生活随笔 收集整理的這篇文章主要介紹了 VS2005混合编译ARM汇编代码 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

2019獨角獸企業重金招聘Python工程師標準>>>

在開發過程中,發現簡單的在Storage Memory區域拷貝或粘貼文件不能達到硬件量測的要求,需要直接通過編寫ARM匯編指令讓CPU直接對Memory進行讀寫數據。

以前沒有用VS2005編寫過匯編代碼,所以走了點彎路,一直試圖用內嵌匯編的方式來build,可恨的VS2005死活不認ARM指令,后來請出 google大神一搜,原來這條路已經有很多先行者試過了,結論是VS2005不能用內嵌匯編的方式build ARM匯編代碼!

俗話說的好啊,機器是死的,人是活的!

google大神給我指出了一條通向光明的道路: VS2005中是可以對純粹的arm匯編文件進行編譯的,當然也可以將C編譯生成的obj文件和asm匯編文件生成的obj文件進行link。

這種混合編譯的方法,網上流傳最廣的一份代碼出自一位叫Larry Bank的老外。

具體方法:

一. 創建編譯規則

<?xml version="1.0" encoding="utf-8"?>
<VisualStudioToolFile Name="Arm ASM" Version="8.00">
?? <Rules>
????? <CustomBuildRule
???????? Name="Arm asm" DisplayName="Arm asm"
???????? CommandLine="armasm -o &quot;$(IntDir)\$(InputName).obj&quot; [$Inputs] "
???????? Outputs="$(IntDir)\$(InputName).obj"
???????? FileExtensions="*.asm"
???????? ExecutionDescription="Executing tool..."
????? >
????? <Properties></Properties>
????? </CustomBuildRule>
?? </Rules>
</VisualStudioToolFile>

將上面的代碼復制到記事本中,并將其保存到vs2005安裝目錄的Microsoft Visual Studio 8\VC\VCProjectDefaults文件夾下,命名為armcc.rules

二. 在VS2005中添加編譯規則

選擇需要和ARM匯編代碼做混合編譯的Project,右鍵彈出的菜單中選擇"Custom Build Rules...”,在彈出的對話框中點"Find Existing..."按鈕,選擇armcc.rules文件

三. 編寫ARM匯編代碼,并將其加入VS2005的Project中(以Larry Bank的code為例)

ARM匯編代碼,文件命名為armtest.asm:

;????? TITLE("Sample App")
;++
??????? AREA sample, CODE, READONLY ; name this block of code
???????
?? EXPORT TEST
IMPORT iGlobal
;
; Called from C as int ARMTEST1(int, int, int, int);
; The first 4 parameters are passed in r0-r3, more parameters would be passed on the stack
;
TEST proc
??? add r0,r0,r1???? ; add all of the inputs together
??? add r0,r0,r2
??? add r0,r0,r3
??? ldr r1,=iGlobal ; get the value of our global variable
??? ldr r1,[r1]?? ; dereference the pointer (I know there's a pipe stall here)
??? add r0,r0,r1 ; we're not concerned with performance in this example
??? mov pc,lr???? ; return to C with the value in R0???
??? endp

??? LTORG????? ; allow room for the address constant of our global (loaded relative to PC)
??? END

將armtest.asm加入VS2005的Project中,編寫調用代碼:

// Windows CE Sample Application

// File Name: MAIN.C
// Demonstrations how to use ARM assembly language within a C program
// Written by Larry Bank 3/25/2007

#include <windows.h>

int iGlobal;

int TEST(int, int, int , int);

/****************************************************************************
*????????????????????????????????????????????????????????????????????????? *
* FUNCTION?? : WinMain(HANDLE, HANDLE, LPSTR, int)??????????????????????? *
*????????????????????????????????????????????????????????????????????????? *
* PURPOSE??? : Program entrypoint???????????????????????????????????????? *
*????????????????????????????????????????????????????????????????????????? *
****************************************************************************/
int APIENTRY WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance, LPWSTR lpCmdLine, int nCmdShow)
{
int iResult;
TCHAR szTemp[256];

?? iGlobal = 5;
?? iResult = TEST(1,2,3,4);
?? wsprintf(szTemp, L"Result = %d", iResult);
?? MessageBox(HWND_DESKTOP, szTemp, L"ASM Result", MB_OK);
??????
?? return 0;

} /* WinMain() */

四. Build VS2005的Project,當你看到如下信息時,恭喜你~~~你成功了!

========= Rebuild All: 1 succeeded, 0 failed, 0 skipped ==========

到這里,可能大家覺得結束了,呵呵,其實才是做了一半!

仔細的朋友可能也發現了,Larry Bank調用armtest.asm中函數的文件MAIN.C在VS2005編譯時調用的是C編譯器,但是現在很多項目工程會以C++代碼編寫(*.cpp),在VS2005中會用C++編譯器Compile。

如果不注意這點的話,就會出現下面的結果:

error LNK2001: unresolved external symbol iGlobal
error LNK2019: unresolved external symbol "int __cdecl TEST1(int,int,int,int)" (?TEST1@@YAHHHHH@Z) referenced in function wmain
fatal error LNK1120: 2 unresolved externals

出現這個問題原因是:

匯編源文件再編譯以后,函數名稱以及變量名稱沒有做任何的更改,而C++源碼在經過C++編譯器編譯以后,函數名稱和變量名稱都已經有過變化(可查看編譯后的object文件),所以連接的時候會報錯。

解決的辦法有下列幾種:

方法一

將匯編中的函數名稱和變量名稱都更改為C++編譯器編譯過的函數名稱和變量名稱,即?TEST1@@YAHHHHH@Z和?iGlobal@@3HA。注意這種方式在名稱前面要加上“|”符號。

;????? TITLE("Sample App")
;++
??????? AREA armtest, CODE, READONLY ; name this block of code

??? IMPORT |?iGlobal@@3HA|
??? EXPORT |?TEST1@@YAHHHHH@Z|
;
; Called from C as int ARMTEST1(int, int, int, int);
; The first 4 parameters are passed in r0-r3, more parameters would be passed on the stack
;
|?TEST1@@YAHHHHH@Z| proc
??? add r0,r0,r1???? ; add all of the inputs together
??? add r0,r0,r2
??? add r0,r0,r3
??? ldr r1,=iGlobal;|?iGlobal@@3HA| ; get the value of our global variable
??? ldr r1,[r1]?? ; dereference the pointer (I know there's a pipe stall here)
??? add r0,r0,r1 ; we're not concerned with performance in this example
??? mov pc,lr???? ; return to C with the value in R0???
??? endp

??? LTORG????? ; allow room for the address constant of our global (loaded relative to PC)
??? END

方法二

在C++源程序中聲明變量和函數的時候用extern "C"修飾,直接告訴編譯器這是C函數。

extern "C"
{

???? int iGlobal;
???? int TEST1(int, int, int , int);
}

轉載于:https://my.oschina.net/tonyyang/blog/15031

創作挑戰賽新人創作獎勵來咯,堅持創作打卡瓜分現金大獎

總結

以上是生活随笔為你收集整理的VS2005混合编译ARM汇编代码的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。