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 "$(IntDir)\$(InputName).obj" [$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汇编代码的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 计算机专业建设委员会会议记录,第一次专业
- 下一篇: mysql 搭建日志服务器_一、架构01