SH-4 Inline Assembly Parameters (Windows CE 5.0)

Send Feedback

The syntax of the __asm intrinsic call is:

__asm(string[,expression...]);

You can pass parameters to a __asm intrinsic call using the list of expressions. The compiler processes the list of expression values in exactly the same way a function call with variable arguments. The compiler treats the first expression in the list as the first argument.

Integer and Non-scalar Parameters

In most circumstances, the first four 32-bit words of integer or non-scalar arguments are passed in registers R4-R7. The remaining words are placed on the stack frame, starting at a displacement of 16 bytes from the stack pointer.

The following code example shows how to access parameters from registers and local argument stack space according to the calling standards.

__asm(
   "add     R4,R5         ; add first two numbers\n"
   "add     R5,R6         ; add third number\n"
   "add     R6,R7         ; add fourth number\n"
   "mov.l   @(16,SP), R0  ; retrieve fifth number\n"
   "add     R0,R7         ; add fifth number\n"
   "mov.l   @(20,SP), R0  ; get address of result\n"
   "mov.l   R7,@R0         ; save results"
   ,num1    // passed in R4
   ,num2    // passed in R5
   ,num3    // passed in R6
   ,1000    // passed in R7
   ,0xFFFF  // passed in stack at a displacement of 16 bytes from SP
   ,&result // passed in stack at a displacement of 20 bytes from SP
   );

Floating-point and Double Parameters

To pass a floating-point argument into a __asm block, pass the address of the argument, and then load the argument to a register within the __asm block.

Because the __asm prototype specifies a variable argument list, passing parameters of type floating-point and double is governed by the SH-4 calling standard for variable argument list.

If a function is declared to use variable argument lists, floating-point registers are unused and floating-point arguments are passed using only the integer argument registers and the stack.

In addition, the C and C++ ANSI standards require that float arguments in a variable argument list be promoted to type double. Consequently, floating point arguments are promoted to type double, and passed as word pairs in the integer registers and or on the stack.

The following code example shows how to first pass the address of float arguments to __asm call and then load the argument to a register within the __asm statement.

//
// Compute x+y+z --> result
//
float add_trig(float x, float y, float z)
{
  float result;
  void * temp_stk_space = _alloca(8);  // Reserve temp space in stack
  __asm(
    "mov.l  @(20,sp), r0  ; get pointer to temp stack space \n"
    "mov.l  r6,  @r0      ; save pointer to z on stack \n"
    "mov.l  r7,  @(4,r0)  ; save pointer to result on stack \n"
    "mov.l  @r4,  r4      ; get x  \n"
    "mov.l  @(16, sp),r0  ; get address of add routine \n"
    "jsr    @r0           ; compute x+y \n"
    "mov.l  @r5,  r5     ; get y  \n"
    "mov    r0, r4       ; get x + y \n" 
    "mov.l  @(20,sp), r1 ;\n"
    "mov.l  @(16, sp),r0 ; get address of add routine \n"
    "mov.l  @r1, r5      ; get pointer to z  \n"
    "jsr    @r0          ; compute x+y+z \n"
    "mov.l  @r5,  r5     ; get z \n"
    "mov.l  @(20,sp), r1 ; get pointer to temp stack space \n"
    "mov.l  @(4,r1),  r1 ; get pointer to result \n"
    "mov.l  r0, @r1      ; store r0 into result addr \n",
    &x,      // pointer to x passed in r4
    &y,      // pointer to y passed in r5
    &z,      // pointer to z passed in r6
    &result, // pointer to result passed in r7 
     _adds,  // pointer to _adds routine passed in @(16,sp)
    temp_stk_space);  // pointer to temp stack space passed in // @(20,sp)

  return result;
}
void main()
{
  float  retval = add_trig(1.0f, 2.0f,3.0f);
  printf("%f\n", retval);
}

See Also

Elements of the SH-4 __asm Block

Send Feedback on this topic to the authors

Feedback FAQs

© 2006 Microsoft Corporation. All rights reserved.