/
// macros
/
// the following examples are given
// for x86 in MASM syntax. Some of these
// macros might not need to be implemented
// in inline assembly, depending on the arch,
// but likely most of them will.
// this macro stores the values in the input
// registers in the ArchRegParms structure passed as 'regparms'.
// In the example below we store ecx and edx because
// they are used in the fastcall convention to pass
// parameters.
// 存储“输入寄存器”中的值到regparms中。
#define ARCH_SAVE_REGPARMS(regparms) \
__asm__( " str %%r0, %0; \
str %% r1, % 1 ; \
str %% r2, % 2 ; \
str %% r3, % 3 ; \
str %% r4, % 4 ; \
str %% r5, % 5 ; \
str %% r6, % 6 ; \
str %% r7, % 7 ; " : \
" =m " ((regparms).a1), \
" =m " ((regparms).a2), \
" =m " ((regparms).a3), \
" =m " ((regparms).a4), \
" =m " ((regparms).d0), \
" =m " ((regparms).d1), \
" =m " ((regparms).d2), \
" =m " ((regparms).d3) :: );
// this macro does two things: copies the values
// stored in regparms into the input registers,
// and calls the function pointed to by the pointer
// ep.
// 复制regparms中的值到“输入寄存器”中,并调用指针ep指向的函数。
#define ARCH_CALL(regparms, ep) \
__asm__( " ldr %%r0, %0; \
ldr %% r1, % 1 ; \
ldr %% r2, % 2 ; \
ldr %% r3, % 3 ; \
ldr %% r4, % 4 ; \
ldr %% r5, % 5 ; \
ldr %% r6, % 6 ; \
ldr %% r7, % 7 ; \
ldr %% r8, % 8 ; \
bx %% r8; " :: \
" m " ((regparms).a1), \
" m " ((regparms).a2), \
" m " ((regparms).a3), \
" m " ((regparms).a4), \
" m " ((regparms).d0), \
" m " ((regparms).d1), \
" m " ((regparms).d2), \
" m " ((regparms).d3), \
" m " (ep) : \
" r0 " , \
" r1 " , \
" r2 " , \
" r3 " , \
" r4 " , \
" r5 " , \
" r6 " , \
" r7 " , \
" r8 " );
// saves any possible return values in the ArchRetValue
// structure given by archvalue.
// 保存archvalue中任何可能的返回值。
#define ARCH_SAVE_RETURN(archvalue, type) \
__asm__( " str %%r0, %0; \
str %% r1, % 1 ; \
str %% r4, % 2 ; " : \
" =m " ((archvalue).a1), \
" =m " ((archvalue).a2), \
" =m " ((archvalue).d0) :: );
// stores the return values in the ArchRetValue structure
// into any place where a caller might expect to find them
// 存储archvalue中的值到“调用者”能找到的地方(寄存器)。
#define ARCH_SET_RETURN(archvalue, type) \
__asm__( " ldr %%r0, %0; \
ldr %% r1, % 1 ; \
ldr %% r4, % 2 ; " :: \
" m " ((archvalue).a1), \
" m " ((archvalue).a2), \
" m " ((archvalue).d0) : \
" r0 " , \
" r1 " , \
" r4 " );
// increases the stack size by bcount bytes
#define ARCH_PUT_STACK_BYTES(bcount) \
__asm__( " ldr %%r8, %0; \
sub %% sp, %% sp, %% r8; " :: \
" m " (bcount) : \
" r8 " , \
" sp " );
// decreases the stack size by bcount bytes
#define ARCH_REMOVE_STACK_BYTES(bcount) \
__asm__( " ldr %%r8, %0; \
add %% sp, %% sp, %% r8; " :: \
" m " (bcount) : \
" r8 " , \
" sp " );
// copies the current stack pointer into the pointer variable
// stackp
#define ARCH_GET_STACK(stackp) \
__asm__( " str %%r13, %0; " : " =m " (stackp) :: );
// copies the current frame pointer into the pointer variable
// framep
#define ARCH_GET_FRAME_PTR(framep) \
__asm__( " str %%r11, %0; " : " =m " (framep) :: );
// macros
/
// the following examples are given
// for x86 in MASM syntax. Some of these
// macros might not need to be implemented
// in inline assembly, depending on the arch,
// but likely most of them will.
// this macro stores the values in the input
// registers in the ArchRegParms structure passed as 'regparms'.
// In the example below we store ecx and edx because
// they are used in the fastcall convention to pass
// parameters.
// 存储“输入寄存器”中的值到regparms中。
#define ARCH_SAVE_REGPARMS(regparms) \
__asm__( " str %%r0, %0; \
str %% r1, % 1 ; \
str %% r2, % 2 ; \
str %% r3, % 3 ; \
str %% r4, % 4 ; \
str %% r5, % 5 ; \
str %% r6, % 6 ; \
str %% r7, % 7 ; " : \
" =m " ((regparms).a1), \
" =m " ((regparms).a2), \
" =m " ((regparms).a3), \
" =m " ((regparms).a4), \
" =m " ((regparms).d0), \
" =m " ((regparms).d1), \
" =m " ((regparms).d2), \
" =m " ((regparms).d3) :: );
// this macro does two things: copies the values
// stored in regparms into the input registers,
// and calls the function pointed to by the pointer
// ep.
// 复制regparms中的值到“输入寄存器”中,并调用指针ep指向的函数。
#define ARCH_CALL(regparms, ep) \
__asm__( " ldr %%r0, %0; \
ldr %% r1, % 1 ; \
ldr %% r2, % 2 ; \
ldr %% r3, % 3 ; \
ldr %% r4, % 4 ; \
ldr %% r5, % 5 ; \
ldr %% r6, % 6 ; \
ldr %% r7, % 7 ; \
ldr %% r8, % 8 ; \
bx %% r8; " :: \
" m " ((regparms).a1), \
" m " ((regparms).a2), \
" m " ((regparms).a3), \
" m " ((regparms).a4), \
" m " ((regparms).d0), \
" m " ((regparms).d1), \
" m " ((regparms).d2), \
" m " ((regparms).d3), \
" m " (ep) : \
" r0 " , \
" r1 " , \
" r2 " , \
" r3 " , \
" r4 " , \
" r5 " , \
" r6 " , \
" r7 " , \
" r8 " );
// saves any possible return values in the ArchRetValue
// structure given by archvalue.
// 保存archvalue中任何可能的返回值。
#define ARCH_SAVE_RETURN(archvalue, type) \
__asm__( " str %%r0, %0; \
str %% r1, % 1 ; \
str %% r4, % 2 ; " : \
" =m " ((archvalue).a1), \
" =m " ((archvalue).a2), \
" =m " ((archvalue).d0) :: );
// stores the return values in the ArchRetValue structure
// into any place where a caller might expect to find them
// 存储archvalue中的值到“调用者”能找到的地方(寄存器)。
#define ARCH_SET_RETURN(archvalue, type) \
__asm__( " ldr %%r0, %0; \
ldr %% r1, % 1 ; \
ldr %% r4, % 2 ; " :: \
" m " ((archvalue).a1), \
" m " ((archvalue).a2), \
" m " ((archvalue).d0) : \
" r0 " , \
" r1 " , \
" r4 " );
// increases the stack size by bcount bytes
#define ARCH_PUT_STACK_BYTES(bcount) \
__asm__( " ldr %%r8, %0; \
sub %% sp, %% sp, %% r8; " :: \
" m " (bcount) : \
" r8 " , \
" sp " );
// decreases the stack size by bcount bytes
#define ARCH_REMOVE_STACK_BYTES(bcount) \
__asm__( " ldr %%r8, %0; \
add %% sp, %% sp, %% r8; " :: \
" m " (bcount) : \
" r8 " , \
" sp " );
// copies the current stack pointer into the pointer variable
// stackp
#define ARCH_GET_STACK(stackp) \
__asm__( " str %%r13, %0; " : " =m " (stackp) :: );
// copies the current frame pointer into the pointer variable
// framep
#define ARCH_GET_FRAME_PTR(framep) \
__asm__( " str %%r11, %0; " : " =m " (framep) :: );
主要说一下AT&T ASM内嵌的写法,格式如下:
__asm__("指令" : "操作约束” (输出参数) : (输入参数) : 寄存器约束 );
指令:当然就是ARM的汇编指令了,但要注意的是寄存器要用%%来约束,以防与参数%冲突。
操作约束( OperationConstraint) :我个人理解为参数传递方式,如:"=m",中“=”表示输出,还可以不写表示输入,"+"表示输 入和输出, “m”表示使用内存,在x86中,还可以是“a”、“b”、“c”等,表示使用什么样的寄存器。
输出参数:对应C代码中变量,通过是由汇编代码从寄存器或内存中取出来的值,以便在C代码中使用。多个参数时,用逗号分 隔。
输入参数:C代码向汇编代码输入的参数。
寄存器约束(Register Constraint): 个人感觉是给“编译器”看的,帮你检查代码,防止你修改了不该改的寄存器的内容。
在ARM中,寄存器与X86上的不同,没ax、bx什么的,它是r0~r15,其中还包括几个特殊用途的寄存器,如:r11=fp(帧指针)、r13=sp(堆栈指针)等。