星期四, 9月 28, 2006

Writting ARM Assembly in Embedded VC

這一篇也是轉貼,因為只有找到這一篇,所以copy下來。
是從packetmatrix forume 看到的一篇 ( http://www.pocketmatrix.com/forums/viewtopic.php?t=4063 )
內容說明在embedded VC++ 內使用assembly language。
專注在ARM。

因為embedded VC++ 的IDE要create source file,沒有assembly filed可以選,還有有關C- Assembly 間的argument passing 規則,不知道MS和ADS一不一樣。
以下就是說明。

------------------------------------------------------------------------------

1) Is there a good book about ARM assembler?
2) Can I use inline assembler in my c code with Embedded Visual C++?
3) Can I see what assembler code the c compiler creates?
4) How do I add an assembley source file to my project, and get EVC to assemble it?
5) How do I write a function in assembler and call it from the c code?
6) How are values passed to and from the assembler function?
7) Can I use any of the 16 registers for anything?
8) Useful resources.


--------------------------------------------------------------------------------

1) Is there a good book about ARM assembler.

ARM System-on-chip architecture (second edition)
Steve Furber
Addison-Wesley

As well as some chapters aimed more at hardware designers, it has an explanation of the ARM instruction set plus a complete reference of the assembler format for each one. It doesnt teach programming in any way, but if you are experienced in c programming and just need full details of the instruction set and info on how the processor works it is great.

2) Can I use inline assembler in my c code with Embedded Visual C++?

There is no supported way of doing this. You need to put your assembler in seperate functions which can be called from your c code. See below for details of how to do this.

3) Can I see what assembler code the c compiler creates?

Yes, and this is very useful for a few reasons. You can see how optimal the code being produced is, and also learn how the compiler does things. You need to:

From the 'Project' menu choose 'Settings'. Go to the 'C/C++' tab. In the 'Category' drop-down-list choose 'Listing Files'. In the 'Listing file type' drop-down-list choose 'Assembley with Source Code'.

Now the compiler will produce .asm files in the output directory which contain the assembler code with the c source as comments.

4) How do I add an assembley source file to my project, and get EVC to assemble it?

Create a blank file 'myfile.asm' in your project directory with notepad. From the menu in EVC select 'Project->Add to Project->Files' set the 'Files of type' field to 'All Files' and select the myfile.asm file. It will appear in the file list on the left, drag it into the 'Source Files' section.

Select 'Project->Settings' from the menu. On the left of the dialog: select the 'ARM release' configuration and select the 'myfile.asm' file. On the right of the dialog: select the 'Custom Build' tab. In the 'Commands' box add the text 'armasm myfile.asm' and in the 'Outputs' box add the text 'myfile.obj'. Repeat this for the 'ARM debug' configuration.

Now you can open and edit myfile.asm from EVC and it will be assembled into your project.

5) How do I write a function in assembler and call it from the c code?

First a note about the assembler source code layout. All command lines should begin with a tab. Any lines that have text on the left are labels. You need to use labels for function names and as targets for branch instructions. Use a semicolon to mark the rest of a line as a comment. The file should finish with an END command.

Example file:

Code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
AREA ArmGfxLib,CODE,READONLY
EXPORT FunctionA
EXPORT FunctionB

FunctionA
MOV r12, sp
stmfd sp!, {r4-r11,lr}

; useful code to do something goes here!

ldmfd sp!, {r4-r11,pc}

FunctionB
MOV r12, sp
stmfd sp!, {r4-r11,lr}

; useful code to do something goes here!

ldmfd sp!, {r4-r11,pc}

END

21 lines; 2 keywds; 0 nums; 32 ops; 0 strs; 0 coms Syntactic Coloring v0.3 - Dan East


Explanation: the AREA command gives a name to this code section. The EXPORT command makes those labels available as functions. The stmfd/ldmfd commands save and restore the registers to the stack, so you dont corrupt values that the calling function depends on.

In your c++ code add the line:

#ifdef ARM
extern "C" void FunctionA(int a, int b);
#endif

The #ifdef is because we have written the function in ARM assembler so it isnt available in MIPS/SH3 builds.

6) How are values passed to and from the assembler function?

If you declare a function of the form:

extern "C" int armfunction(int arg1, int arg2, int arg3, int arg4, int arg5, int arg6);

The first 4 arguments will be passed in the registers r0-r3. These registers will contain the passed values at the start of your assembler function. Further arguments are passed on the stack, see the code below to read them.

The return value should be placed into register r0 at the end of your assembler function (just before you return to the caller).

This works well with int's and pointers (all pointers are 32 bits). If you try and pass a structure directly as an argument it gets more complex. I advise you to only pass/return integers and pointers to/from your assembler functions, at least to start with.

Here is an example function (declared as above) which adds its six arguments and returns the result.

Code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
armfunction
MOV r12, sp ; these two lines are
stmfd sp!, {r4-r11,lr} ; standard setup code

; r0-r3 are the first 4 arguments passed

ldr r4, [r12] ; load 5'th argument into r4
ldr r5, [r12, #4] ; load 6'th argument into r5

add r0, r0, r1 ; r0 = r0 + r1
add r0, r0, r2 ; r0 = r0 + r2
add r0, r0, r3 ; r0 = r0 + r3
add r0, r0, r4 ; r0 = r0 + r4
add r0, r0, r5 ; r0 = r0 + r5

ldmfd sp!, {r4-r11,pc} ; standard cleanup and return code

16 lines; 1 keywds; 3 nums; 52 ops; 0 strs; 0 coms Syntactic Coloring v0.3 - Dan East


7) Can I use any of the 16 registers for anything?

No. You can use r0-r12 and r14 for anything you like. r15 is the program counter, if you write a value to it then execution will jump to that location. Use the branch instruction, dont alter it directly. r13 is the stack pointer, do not alter it unless you are sure you know what you are doing. r14 (which you can use) is the link register. If you want to call another function you need to set this to the return address, I will include an example in a future version of this FAQ.

8) Useful resources.
什麼時候要用?

要用 mcr, mrc 和co-processor instruction 時好像就要用到...

沒有留言:

網誌存檔