linux gcc asm,GCC 下 C和ASM混合编程

下面是一个简单的示例程序,这个程序显示了如何实现C和ASM的接口。

Contents:

readme.txt    --  this file

endian_demo.c    --  the C source file, implements the main function

function.S      --  the AT&T-format ASM file, implements the ASM functions

Makefile    --  the makefile for compiling the program

Instructions to Compile:

-----------------------

Just run "make" in the source file folder. If everything goes well, an executable

binary file named "endian_demo" will be created in the same folder.

Instructions to Run:

-------------------

Just run "./endian_demo" in the folder in which the program is compiled. Argument

should be specified in the command line. For example:

./endian_demo 1 255 1334

More than one number should be specified. If no number specified, the program will

print a usage message.

Source Files:

------------------

endian_demo.c :

This is the main C source file of the program. It implements the main()

function, which parses the command-line argument, and invokes the ASM functions

to swap the endian of the number and print the hexadecimal form of the number.

function.S :

This is the AT&T format assembly file which implements the two functions:

writeHexASCII and swapEnds.

To make the assembly code interface the ANSI C code, we need to understand how

the gcc C compiler generating code for the arguments of the functions and the return

value of the functions.

Arguments of a function is passed via the stack of the program. Before invoking

the function, arguments is pushed into the stack, and then call the function. In the

function itself, it should retrive the arguments from the stack, whose current

address is stored in the esp register of the x86 CPU.

Return value is passed via the register eax. The function puts the return value

in eax, then a "ret" instruction will return to the place where this functions is

invoked.

void writeHexASCII(char *buffer,unsigned int number);

This function takes two arguments, the address of the buffer and the number to

be converted to hexadecimal strings. Each digits of the hex value is extracted from

the number using the shifting instruction, then converted to hex value, and then

moved to the buffer.

unsigned int swapEnds(unsigned int x);

This functions takes one argument and returns the swapped value.  The bytes

of the number is extracted and swapped, and then return the value in eax register.

Assumptions:

------------

1. The target linux system is running on Intel X86 32-bit CPU

2. GNU make and gcc are installed on the system.

以下是代码:

这个是主程序文件endian_demo.c

15448_0.gif

#include

15448_0.gif

#include

15448_0.gif

extern void

writeHexASCII(char

*buffer,unsignedint

number);

15448_0.gifextern

unsignedint

swapEnds(unsignedint

x);

15448_0.gif

int

main(int

arg_c,char

**arg_v)

15448_0.gif

{

15448_0.gif    int

i;

15448_0.gif

unsignedint

num, num_swap;

15448_0.gif    char

buf[16];

15448_0.gif

if

(arg_c < 2)

15448_0.gif

{

15448_0.gif

fprintf(stderr,"Usage: %s NUM1 NUM2 NUM3...n"

, arg_v[0]);

15448_0.gif  return

-1;

15448_0.gif

}

15448_0.gif

i = 1;

15448_0.gif    while

(i < arg_c)

15448_0.gif

{

15448_0.gif

num = atoi(arg_v[i]);

15448_0.gif

num_swap = swapEnds(num);

15448_0.gif

fprintf(stdout,"%d: "

, num);

15448_0.gif

writeHexASCII(buf, num);

15448_0.gif

fprintf(stdout,"%s "

, buf);

15448_0.gif

writeHexASCII(buf, num_swap);

15448_0.gif

fprintf(stdout,"%s = "

, buf);

15448_0.gif

fprintf(stdout,"%dn"

, num_swap);

15448_0.gif

i++;

15448_0.gif

}

15448_0.gif

return

0;

15448_0.gif

}

这个是实现endian swap和hex转字符串的函数,文件名function.S

/* here we use AT&T format assembly */

.text

.code32

.globl    writeHexASCII

.globl    swapEnds

/*

0x8(%esp) = number

0x4(%esp) = *buffer

%ecx = shift length

%eax = hex value

%edi = loop count

*/

writeHexASCII:

movl   $28,%ecx

movl   $0,%edi

mov    0x4(%esp),%edx

jmp    if_loop_end

loop_start:

mov    0x8(%esp),%eax

shr    %cl,%eax

and    $0xf,%eax

cmpl   $9,%eax

jg     hex_abcdef

hex_0_9:

addl   $0x30,%eax

jmp    hex_convert_complete

hex_abcdef:

addl   $0x57,%eax

hex_convert_complete:

mov    %al,(%edx)

add    $1,%edx

subl   $4,%ecx

addl   $1,%edi

if_loop_end:

cmpl   $7,%edi

jle    loop_start

movb   $0x0,(%edx)

ret

/*

0x4(%esp) = x

%edi = temp value

*/

swapEnds:

mov    4(%esp),%eax

and    $0xff000000,%eax

shr    $24,%eax

mov    %eax,%edi

movzbl 4(%esp),%eax

shl    $24,%eax

or     %eax,%edi

mov    4(%esp),%eax

and    $0xff0000,%eax

shr    $8,%eax

or     %eax,%edi

mov    4(%esp),%eax

and    $0xff00,%eax

shl    $8,%eax

or     %eax,%edi

mov    %edi,%eax

ret

下面是一个简单的Makefile,用来编译这个程序:

all:    endian_demo

endian_demo:    function.o endian_demo.o

gcc -o $@ function.o endian_demo.o

function.o:    function.S

gcc -o $@ -c $<

endian_demo.o:    endian_demo.c

gcc -o $@ -c $< -ansi

clean:

rm -f *.o

rm -f endian_demo

几个常用的国外干私活兼职网站

兼职编程、开发, C/C++/C#, PHP, Web开发, ASP, 外包项目, 接国外私活, 程序员兼职, 外包开发, 国外项目外包, 网站外包项目

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值