之前的扩展asm格式里,介绍了如何通过寄存器来访问C程式里的变量,其实还可以直接使用变量的内存位置来访问变量的值,例如下面的memtest.c程式...
/* memtest.c - An example of using memory locations as values */ #include <stdio.h> int main() { int dividend = 20; int divisor = 5; int result; asm("divb %2\n\t" "movl %1, %0" : "=m"(result) : "a"(dividend), "m"(divisor)); printf("The result is %d\n", result); return 0; } |
$ gcc -o memtest memtest.c $ ./memtest The result is 4 $ gcc -S memtest.c $ cat memtest.s ............................ ............................ movl $20, 28(%esp) movl $5, 24(%esp) movl 28(%esp), %eax #APP # 9 "memtest.c" 1 divb 24(%esp) movl %eax, 20(%esp) # 0 "" 2 #NO_APP movl 20(%esp), %edx movl $.LC0, %eax movl %edx, 4(%esp) movl %eax, (%esp) call printf ............................ ............................ $ |
asm( “fsincos” : “=t”(cosine), “=u”(sine) : “0”(radian)); |
/* sincostest.c - An example of using two FPU registers */
#include <stdio.h>
int main()
{
float angle = 90;
float radian, cosine, sine;
radian = angle / 180 * 3.14159;
asm("fsincos"
:"=t"(cosine), "=u"(sine)
:"0"(radian));
printf("The cosine is %f, and the sine is %f\n", cosine, sine);
return 0;
}
|
$ gcc -o sincostest sincostest.c $ ./sincostest The cosine is 0.000001, and the sine is 1.000000 $ |
$ gcc -S sincostest.c $ cat sincostest.s ............................ ............................ flds 40(%esp) #APP # 9 "sincostest.c" 1 fsincos # 0 "" 2 #NO_APP ............................ fstps 52(%esp) ............................ fstps 48(%esp) ............................ ............................ $ |
/* areatest.c - An example of using floating point regs */ #include <stdio.h> int main() { int radius = 10; float area; asm("fild %1\n\t" "fimul %1\n\t" "fldpi\n\t" "fmul %%st(1), %%st(0)" : "=t"(area) :"m"(radius) : "%st(1)"); printf("The result is %f\n", area); return 0; } |
/* jmptest.c - An example of using jumps in inline assembly */ #include <stdio.h> int main() { int a = 10; int b = 20; int result; asm("cmp %1, %2\n\t" "jge greater\n\t" "movl %1, %0\n\t" "jmp end\n" "greater:\n\t" "movl %2, %0\n" "end:" :"=r"(result) :"r"(a), "r"(b)); printf("The larger value is %d\n", result); return 0; } |
$ gcc -S jmptest.c $ cat jmptest.s ............................... ............................... #APP # 9 "jmptest.c" 1 cmp %eax, %edx jge greater movl %eax, %ebx jmp end greater: movl %edx, %ebx end: ............................... ............................... $ |
/* jmptest2.c - An example of using generic jumps in inline assembly */ #include <stdio.h> int main() { int a = 10; int b = 20; int result; asm("cmp %1, %2\n\t" "jge 0f\n\t" "movl %1, %0\n\t" "jmp 1f\n " "0:\n\t" "movl %2, %0\n " "1:" :"=r"(result) :"r"(a), "r"(b)); printf("The larger value is %d\n", result); return 0; } |
#define NAME expression |
#define MAX_VALUE 1024 |
data = MAX_VALUE; if (size > MAX_VALUE) |
data = 1024 if (size > 1024) |
#define NAME(input values, output value) (function) |
/* mactest1.c - An example of a C macro function */ #include <stdio.h> #define SUM(a, b, result) \ ((result) = (a) + (b)) int main() { int data1 = 5, data2 = 10; int result; float fdata1 = 5.0, fdata2 = 10.0; float fresult; SUM(data1, data2, result); printf("The result is %d\n", result); SUM(1, 1, result); printf("The result is %d\n", result); SUM(fdata1, fdata2, fresult); printf("The floating result is %f\n", fresult); SUM(fdata1, fdata2, result); printf("The mixed result is %d\n", result); return 0; } |
$ gcc -E mactest1.c ....................... ....................... int main() { int data1 = 5, data2 = 10; int result; float fdata1 = 5.0, fdata2 = 10.0; float fresult; ((result) = (data1) + (data2)); printf("The result is %d\n", result); ((result) = (1) + (1)); printf("The result is %d\n", result); ((fresult) = (fdata1) + (fdata2)); printf("The floating result is %f\n", fresult); ((result) = (fdata1) + (fdata2)); printf("The mixed result is %d\n", result); return 0; } $ |
/* mactest2.c - An example of using inline assembly macros in a program */ #include <stdio.h> #define GREATER(a, b, result) ({ \ asm("cmp %1, %2\n\t" \ "jge 0f\n\t" \ "movl %1, %0\n\t" \ "jmp 1f\n\t" \ "0:\n\t" \ "movl %2, %0\n\t" \ "1:" \ :"=r"(result) \ :"r"(a), "r"(b)); }) int main() { int data1 = 10; int data2 = 20; int result; GREATER(data1, data2, result); printf("a = %d, b = %d result: %d\n", data1, data2, result); data1 = 30; GREATER(data1, data2, result); printf("a = %d, b = %d result: %d\n", data1, data2, result); return 0; } |
$ gcc -E mactest2.c ......................... ......................... int main() { int data1 = 10; int data2 = 20; int result; ({ asm("cmp %1, %2\n\t" "jge 0f\n\t" "movl %1, %0\n\t" "jmp 1f\n\t" "0:\n\t" "movl %2, %0\n\t" "1:" :"=r"(result) :"r"(data1), "r"(data2)); }); printf("a = %d, b = %d result: %d\n", data1, data2, result); data1 = 30; ({ asm("cmp %1, %2\n\t" "jge 0f\n\t" "movl %1, %0\n\t" "jmp 1f\n\t" "0:\n\t" "movl %2, %0\n\t" "1:" :"=r"(result) :"r"(data1), "r"(data2)); }); printf("a = %d, b = %d result: %d\n", data1, data2, result); return 0; } $ |