The following is a simple example program that shows how to implement the C and ASM interfaces.
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
Shocould be specified in the command line. For example:
./Endian_demo 1 255 1334
More than one number shocould 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
Function itself, it shocould 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
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.
The following code is used:
This is the main program file endian_demo.c.
650) this. width = 650; "align =" top "alt =" "src = \ '# \'"/editer/InBlock.gif "/>#include <stdio. h>
650) this. width = 650; "align =" top "alt =" "src = \ '# \'"/editer/InBlock.gif "/>#include <stdlib. h>
650) this. width = 650; "align =" top "alt =" "src = \ '# \'"/editer/InBlock.gif "/>
Extern void writeHexASCII (char * buffer, unsigned int number );
650) this. width = 650; "align =" top "alt =" "src = \' # \ '"/editer/InBlock.gif "/> extern unsigned int swapEnds (unsigned int x );
650) this. width = 650; "align =" top "alt =" "src = \ '# \'"/editer/InBlock.gif "/>
Int main (int arg_c, char ** arg_v)
650) this. width = 650; "align =" top "alt =" "src = \ '# \'"/editer/InBlock.gif "/> {
650) this. width = 650; "align =" top "alt =" "src = \ '# \'"/editer/InBlock.gif "/> int I;
650) this. width = 650; "align =" top "alt =" "src = \ '# \'"/editer/InBlock.gif "/> unsigned int num, num_swap;
650) this. width = 650; "align =" top "alt =" "src = \ '# \'"/editer/InBlock.gif "/> char buf [16];
650) this. width = 650; "align =" top "alt =" "src = \ '# \'"/editer/InBlock.gif "/>
If (arg_c <2)
650) this. width = 650; "align =" top "alt =" "src = \ '# \'"/editer/InBlock.gif "/> {
650) this. width = 650; "align =" top "alt =" "src = \ '# \'"/editer/InBlock.gif "/> fprintf (stderr," Usage: % s NUM1 NUM2 NUM3... \ n ", arg_v [0]);
650) this. width = 650; "align =" top "alt =" "src = \ '# \'"/editer/InBlock.gif "/> return-1;
650) this. width = 650; "align =" top "alt =" "src = \ '# \'"/editer/InBlock.gif "/>}
650) this. width = 650; "align =" top "alt =" "src = \ '# \'"/editer/InBlock.gif "/>
I = 1;
650) this. width = 650; "align =" top "alt =" "src = \ '# \'"/editer/InBlock.gif "/> while (I <arg_c)
650) this. width = 650; "align =" top "alt =" "src = \ '# \'"/editer/InBlock.gif "/> {
650) this. width = 650; "align =" top "alt =" "src = \ '# \'"/editer/InBlock.gif "/> num = atoi (arg_v [I]);
650) this. width = 650; "align =" top "alt =" "src = \ '# \'"/editer/InBlock.gif "/> num_swap = swapEnds (num );
650) this. width = 650; "align =" top "alt =" "src = \ '# \'"/editer/InBlock.gif "/>
Fprintf (stdout, "% d:", num );
650) this. width = 650; "align =" top "alt =" "src = \ '# \'"/editer/InBlock.gif "/> writeHexASCII (buf, num );
650) this. width = 650; "align =" top "alt =" "src = \ '# \'"/editer/InBlock.gif "/> fprintf (stdout, "% s <->", buf );
650) this. width = 650; "align =" top "alt =" "src = \ '# \'"/editer/InBlock.gif "/> writeHexASCII (buf, num_swap );
650) this. width = 650; "align =" top "alt =" "src = \' # \ '"/editer/InBlock.gif "/> fprintf (stdout," % s = ", buf );
650) this. width = 650; "align =" top "alt =" "src = \ '# \'"/editer/InBlock.gif "/> fprintf (stdout," % d \ n ", num_swap );
650) this. width = 650; "align =" top "alt =" "src = \ '# \'"/editer/InBlock.gif "/>
I ++;
650) this. width = 650; "align =" top "alt =" "src = \ '# \'"/editer/InBlock.gif "/>}
650) this. width = 650; "align =" top "alt =" "src = \ '# \'"/editer/InBlock.gif "/>
Return 0;
650) this. width = 650; "align =" top "alt =" "src = \ '# \'"/editer/InBlock.gif "/>}
This is a function for converting endian swap and hex to strings. The file name is 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
The following is a simple Makefile used to compile this program:
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
Several common overseas websites for private and part-time jobsFreelancer.com-the No. 1 software part-time job website part-time programming and development, C/C ++/C #, PHP, Web development, ASP, outsourcing project, foreign private work, programmer part-time, outsourcing development, foreign Project outsourcing, and website Outsourcing
This article is from the "techlife" blog, please be sure to keep this source http://techlife.blog.51cto.com/212583/55348