program stack |
---|
indirect addressing |
Function paramter3 (16(%esp)) |
Function paramter2 (12(%esp)) |
Function paramter1 (8(%esp)) |
Return Address (4(%esp)) |
Old EBP Value ((%esp)) |
寄存器 | 状态 |
---|---|
EAX | 用来存储返回值,可以使用到程序返回前 |
EBX | 被用来指向全局偏移表;值需要保留 |
ECX | 可以使用 |
EDX | 可以使用 |
EBP | 值需要保留 |
ESP | 值需要保留 |
EDI | 值需要保留 |
ESI | 值需要保留 |
ST(0) | 用来存储浮点数返回值,可以使用到程序返回前 |
ST(1)-ST(7) | 可以使用 |
.section .text
.type func, @function
func:
pushl %ebp
movl %esp, %ebp
subl $12, %ebp
pushl %edi
pushl %esi
pushl %ebx
popl %ebx
popl %esi
popl %edi
movl %ebp, %esp
popl %ebp
ret
# asmfunc.s - An example of a simple assembly language function
.section .data
testdata:
.ascii "This is a test message from the asm function\n"
datasize:
.int 45
.section .text
.type asmfunc, @function
.globl asmfunc
asmfunc:
pushl %ebp
movl %esp, %ebp
pushl %ebx
movl $4, %eax
movl $1, %ebx
movl $testdata, %ecx
movl datasize, %edx
int $0x80
popl %ebx
movl %ebp, %esp
popl %ebp
ret
/* mainprog.c - An example of calling an assembly function */
#include
int main()
{
printf("This is a test. \n");
asmfunc();
printf("Now for the second time.\n");
asmfunc();
printf("This is complete the test.\n");
return 0;
}
编译: gcc -o mainprog mainprog.c amsfunc.s
运行: ./mainprog
反汇编: objdump -D mainporg > dump
# sequare.s - An example of a function that returns an integer value
.type square, @function
.globl square
square:
pushl %ebp
movl %esp, %ebp
movl 8(%ebp), %eax
imull %eax, %eax
movl %ebp, %esp
popl %ebp
ret
/* inttest.c - An example fo returning an integer value */
#include
int main()
{
int i = 2;
int j = square(i);
printf("The square of %d is %d\n", i, j);
j = square(10);
printf("The square of 10 is %d\n", j);
return 0;
}
# cpuidfunc.s - An example of returning a string value
.section .bss
.comm output, 13
.section .text
.type cpuidfunc, @function
.globl cpuidfunc
cpuidfunc:
pushl %ebp
movl %ebp, %esp
pushl %ebx
movl $0, %eax
cpuid
movl $output, %edi
movl %ebx, (%edi)
movl %edx, 4(%edi)
movl %ecx, 8(%edi)
movl $output, %eax
popl %ebx
movl %ebp, %esp
popl %ebp
ret
/* stringtest.c - An example of returning a string value */
#include
char * cpuidfunc(void);
int main()
{
char * spValue;
spValue = cpuidfunc();
printf("The CPUID is : %s \n", spValue);
return 0;
}
# areafunc.s - An example of a floating point return value
.section .text
.type areafunc, @function
.globl areafunc
areafunc:
pushl %ebp
movl %ebp, %esp
fldpi
filds 8(%ebp),
fmul %st(0), %st(0)
fmul %st(1), %st(0)
movl %ebp, %esp
popl %ebp
ret
/* floattest.c - An example of using floating point return values */
#include
float areafunc(int);
int main()
{
int radius = 10;
float result;
result = areafunc(radius);
printf("The result is %f\n", result);
result = areafunc(2);
printf("The result is %f\n", result);
return 0;
}
# greater.s - An example of using multiple input values
.section .text
.type greater, @function
.globl greater
greater:
pushl %ebp
movl %esp, %ebp
movl 8(%ebp), %eax
movl 12(%ebp), %ecx
cmpl %ecx, %eax
jge end
movl %ecx, %eax
end:
movl %ebp, %esp
popl %ebp
ret
/* multest.c - An example of using multiple input values */
#include
int main()
{
int i = 10;
int j = 20;
int k = greater(i, j);
printf("The larger value is %d\n", k);
return 0;
}
由于c++中使用c++格式命名函数为了使用汇编必须使用c格式命名规则,所以在声明函数时需要以下格式生命:
extern “C”
{
int square(int);
}
选项 | 描述 |
---|---|
d | 从静态库中删除文件 |
m | 移动静态库中的文件 |
p | 将静态库中的指定文件打印到标准输出 |
q | 快速添加一个文件到静态库 |
r | 替换一个静态库中的文件 |
t | 显示静态库中的文件列表 |
x | 从静态库中提取文件 |
修饰符 | 描述 |
---|---|
a | 向一个存在文件的静态库中添加文件 |
b | 向一个不存在文件的静态库中添加文件 |
c | 创建一个新的静态库 |
f | 截断静态库中的文件名 |
i | 向一个不存在文件的静态库中添加文件 |
P | 在静态库中使用全路径 |
s | 为静态库创建索引 |
u | 更新静态库中的文件 |
v | 使用详细模式 |
静态库的命名格式
libx.a
创建一个静态库
ar r libchap.a square.o cpuidfunc.o areafunc.o greater.o fpmathfunc.o
显示静态库中的文件
ar tv libchap.a
为静态库创建索引
ranlib libchap.a
显示静态库中的符号
nm -s libchap.a | more
使用静态库编译可执行文件
gcc -o inttest inttest.c libchap.a
命名格式
libx.so
生成动态库
gcc -shared -o libchap.so square.o cpuidfunc.o areafunc.o greater.o fpmathfunc.o
生成可执行文件
gcc -o intest -L . -lchap inttest.c
查看可执行文件中的动态库信息
ldd inttest
运行程序
使用LD_LIBRARY_PATH环境变量指定动态库路径
export LD_LIBRARY_PATH="$LD_LIBRARY_PATH:."
ldd inttest
./inttest
使用/etc/ld.so.conf 指定动态库路径
vim /etc/ld.so.conf
ldconfig
ldd inttest
./inttest
as -gstabs -o square.o square.s
gcc -gstabs -o inttest inttest.c square.o
gdb -q inttest