|  | 
5#
 
 
 楼主|
发表于 2010-8-23 17:05:35
|
只看该作者 
使用全局 C 变量
| 仅仅实现汇编代码本身并不能完成很多任务。为了完成实际工作,还需要将数据传进和传出(传进参数与返回结果)。 
 基本内联汇编代码可以利用应用程序中定义的 C 全局变量。注意,只有全局定义的变量才能在基本的内联汇编代码内使用。下面程序演示内联汇编引用 C 中相同的全局变量。
 反汇编后:#include <stdio.h>
 int a = 10;
 int b = 20;
 int result;
 
 int main()
 {
 asm (    "pusha\\n\\t"
 "movl a, %eax\\n\\t"
 "movl b, %ebx\\n\\t"
 "imull %ebx, %eax\\n\\t"
 "movl %eax, result\\n\\t"
 "popa");
 
 printf ("the answer is $d\\n", result);
 return (0);
 }
在 .data 段中,声明了 a 和 b 变量并赋值。由于 result 变量在 C 中并未赋初值,所以被声明为 .comm 。.comm 可以使用第3个参数。它代表符号需要对齐的边界基准(例如, 边界基准为 16 时意味着符号存放地址的最低4位应该是零)。第3个参数表达式结果必须是纯粹的数字,而且一定是2的幂。.file    "global.c".globl a
 .data
 .align 4
 .type    a, @object
 .size    a, 4
 a:
 .long    10
 .globl b
 .align 4
 .type    b, @object
 .size    b, 4
 b:
 .long    20
 .comm    result,4,4
 .section    .rodata
 .LC0:
 .string    "the answer is $d\\n"
 .text
 .globl main
 .type    main, @function
 main:
 pushl    %ebp
 movl    %esp, %ebp
 andl    $-16, %esp
 subl    $16, %esp
 #APP
 # 9 "global.c" 1
 pusha
 movl a, %eax
 movl b, %ebx
 imull %ebx, %eax
 movl %eax, result
 popa
 # 0 "" 2
 #NO_APP
 movl    result, %edx
 movl    $.LC0, %eax
 movl    %edx, 4(%esp)
 movl    %eax, (%esp)
 call    printf
 movl    $0, %eax
 leave
 ret
 .size    main, .-main
 .ident    "GCC: (Ubuntu 4.4.3-4ubuntu5) 4.4.3"
 .section    .note.GNU-stack,"",@progbits
需要注意的是,在内联汇编代码段,开始时使用了 PUSHA 指令,结尾时使用了 POPA 指令。这一工作很重要,因为编译器可能会使用这些寄存器存放其他的值,如果在 asm 段中修改它们,可能会产生不可预料的结果。
 | 
 |