LinuxSir.cn,穿越时空的Linuxsir!

 找回密码
 注册
搜索
热搜: shell linux mysql
查看: 2431|回复: 6

C语言、汇编混合编程示例

[复制链接]
发表于 2007-10-28 21:09:12 | 显示全部楼层 |阅读模式
整理了一下以前学习汇编时写的代码,发上来看看是否对各位有所帮助。

c调用asm写的函数,适用于32位机
main.c

  1. #include <stdio.h>

  2. int printf_minus(int num1, int num2);

  3. int main()
  4. {
  5.         int n1,n2;

  6.         n1=23;
  7.         n2=12;

  8.         printf("c:\n");
  9.         printf("%d - %d = %d\n", n1, n2, n1-n2);

  10.         printf("asm:\n");
  11.         printf_minus(n1,n2);
  12.         return 0;
  13. }
复制代码


function.asm

  1. extern printf
  2. global printf_minus

  3. [section .text]
  4. printf_minus:
  5. mov eax, [esp+4]        ; num1
  6. sub eax, [esp+8]        ; num2
  7. push eax                     ; num1-num2
  8. push dword [esp+12]
  9. push dword [esp+12]
  10. push dword fmt
  11. call printf                   ; printf(fmt, num1, num2, num1-num2);
  12. add esp, 16
  13. ret

  14. fmt:
  15. db "%d - %d = %d",0ah,0
复制代码


编译:
nasm -f elf function.asm
gcc -c main.c
gcc -o test main.o function.o

运行:
./test
c:
23 - 12 = 11
asm:
23 - 12 = 11
 楼主| 发表于 2007-10-30 11:14:55 | 显示全部楼层
再发一个:用汇编获取CPU ID,这回用asm编写库,c调用库

cpuid.asm

  1. extern _GLOBAL_OFFSET_TABLE_

  2. global get_cpuid:function

  3. %macro get_GOT 0
  4. call %%getgot
  5. %%getgot:
  6. pop ebx
  7. add ebx,_GLOBAL_OFFSET_TABLE_+$$-%%getgot wrt ..gotpc
  8. %endmacro

  9. [section .data]
  10. ver db "CPUID library version 0.0.1",0xa,0
  11. len equ $-ver

  12. [section .text]
  13. _start:
  14. get_GOT
  15. mov edx,len
  16. lea ecx,[ebx+ver wrt ..gotoff]
  17. mov ebx,1
  18. mov eax,4
  19. int 0x80
  20. mov ebx,0
  21. mov eax,1
  22. int 0x80

  23. get_cpuid:
  24. push edi
  25. mov edi,[esp+8]
  26. push ebx
  27. push ecx
  28. push edx
  29. xor eax,eax
  30. cpuid
  31. mov [edi],ebx
  32. mov [edi+4],edx
  33. mov [edi+8],ecx
  34. mov [edi+12],byte 0
  35. pop edx
  36. pop ecx
  37. pop ebx
  38. pop edi
  39. ret
复制代码


cpuid.h

  1. #ifndef _CPUID_H
  2. #define _CPUID_H        1

  3. void get_cpuid(char *buf);

  4. #endif
复制代码


  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include "cpuid.h"

  4. int main(int argc, char *argv[])
  5. {
  6.         char buf[16];

  7.         get_cpuid(buf);
  8.         printf("The processor vender is "%s"\n", buf);
  9.         exit(EXIT_SUCCESS);
  10. }
复制代码


编译:
nasm -f elf cpuid.asm
ld -shared -o libcpuid.so cpuid.o
gcc -o demo demo.o -L. -lcpuid

运行:
./libcpuid.so
CPUID library version 0.0.1

env LD_LIBRARY_PATH=. ./demo
The processor vender is "GenuineIntel"


静态库:
nasm -f elf cpuid.asm
ar cr libcpuid.a cpuid.o
gcc -o demo demo.o libcpuid.a

./demo
The processor vender is "GenuineIntel"
回复 支持 反对

使用道具 举报

发表于 2007-10-31 00:33:51 | 显示全部楼层
very good!
回复 支持 反对

使用道具 举报

发表于 2007-11-7 13:42:20 | 显示全部楼层
Post by fly0365;1775537
very good!


能不能总结一下?
回复 支持 反对

使用道具 举报

发表于 2007-11-11 22:41:26 | 显示全部楼层
第一个就是一个参数传递的问题
有个小难点就是
push dword [esp+12]
push dword [esp+12]
其实没什么,就是堆栈在不断的增长
第二个程序,我曾经做过一个dos版本的。其主要技术就是使用了一个cpuid指令
那些宏着实的很迷惑人。
回复 支持 反对

使用道具 举报

发表于 2007-11-11 22:50:28 | 显示全部楼层
为什么会有这一段?请高手指教~!看样子像是系统功能的调用.但是具体是干什么的为什么要有,不晓得的
_start:
get_GOT
mov edx,len
lea ecx,[ebx+ver wrt ..gotoff]
mov ebx,1
mov eax,4
int 0x80
mov ebx,0
mov eax,1
int 0x80
回复 支持 反对

使用道具 举报

发表于 2007-11-11 22:59:08 | 显示全部楼层
上边的问题经过查找发现是
  .long SYMBOL_NAME(sys_exit)/*1*/
  .long SYMBOL_NAME(sys_fork)
  .long SYMBOL_NAME(sys_read)
  .long SYMBOL_NAME(sys_write)/*4*/
看来那两个系统调用是用来显示什么的。第一个很可能就是显示lea ecx,[ebx+ver wrt ..gotoff]的字符串。第二个结束程序.
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 注册

本版积分规则

快速回复 返回顶部 返回列表