2.5 OpenEuler 中C与汇编的混合编程(选做)
0.任务详情
1. 在X86_64架构下实践2.5中的内容,提交代码和实践截图
2. 把2.5的内容在OpenEuler中重新实践一遍,提交相关代码和截图
3. 实验内容要经过答辩才能得到相应分数
1.首先在x86_64kali中实践内容。
1.1
入口代码
函数体代码
退出代码
1.2
这里有点绕,得分两个文件进行编译,一个是s.s,另一个是s.c,将两份文件编译成.o文件再一起编译成可执行文件。
1.3
这里编译出现问题是因为编译环境应该是32位的,这里的pop和push产生的是32位,但是系统环境应该是64位的,所以类型不匹配,需要再过程中加上-m32。(或者将所有指令都换成xxxl是否可行?)
参考博客:https://www.codenong.com/21245245/
1.4
这里问题与上面相同,编译加上-m32即可通过。
代码链接:https://gitee.com/sister_ben/kali/tree/master/test2-5
2.接下来在树莓派openeuler中完成。
在openeuler中的源都没有有关32位库的安装包,无法安装32位编译环境,所以将32位编译代码改为64位代码。
操作环境:openeuler
2.5.1用汇编代码编程
a.c file
#include <stdio.h>
extern int B();
int A(int x, int y){
int d, e, f;
d = 4;
e = 5;
f = 6;
f = B(d,e);
}
a.s file
A:
pushq %rbp
movq %rsp, %rbp
subq $32, %rsp
movl %edi, -20(%rbp)
movl %esi, -24(%rbp)
movl $4, -4(%rbp)
movl $5, -8(%rbp)
movl $6, -12(%rbp)
movl -8(%rbp), %edx
movl -4(%rbp), %eax
movl %edx, %esi
movl %eax, %edi
movl $0, %eax
call B
movl %eax, -12(%rbp)
leave
ret
2.5.2用汇编语言实现函数
获取CPU寄存器
s.s file
.globl get_esp, get_ebp
get_esp:
movq %rsp, %rax
ret
get_ebp:
movq %rsp, %rax
ret
print.c
#include <stdio.h>
int main(){
int ebp, esp;
ebp = get_ebp();
esp = get_esp();
printf("rbp=%8x rsp=%8x\n", ebp, esp);
}
运行截图
用汇编语言编写mysum函数
mysum.s
.text
.global mysum, printf
mysum:
pushq %rbp movq %rsp, %rbp
movl %edi, -4(%rbp) movl %esi, -8(%rbp)
movl -8(%rbp), %eax addl -4(%rbp), %eax
popq %rbp
ret
sum.c
#include <stdio.h>
int main(){
int a, b, c;
a = 123;
b = 456;
c = mysum(a, b);
printf("c=%d\n",c);
}
编译截图
2.5.3从汇编中调用C函数
sub.s
.text
.global sub, a, d, printf
sub:
pushq %rbp
movq %rsp, %rbp
movl b, %edx
movl a, %esi
movl $fmt, %edi
call printf
leave
ret
.data
fmt: .asciz "a=%d b=%d\n"
submain.c
#include <stdio.h>
int a, b;
int main(){
a = 100;
b = 200;
sub();
}
编译运行截图