OpenEuler 中C语言中的函数调用测试
OpenEuler 中C语言中的函数调用测试
20191331 lyx
实践任务
1. 在X86_64架构下实践2.4中的内容
2. 通过GDB查看寄存器的内容,把教材中的图填入具体的值
3. 把2.4的C代码在OpenEuler中重新实践一遍,绘制出ARM64的逻辑框图
4. 实验内容要经过答辩才能得到相应分数
一、在OpenEuler下实践2.4内容
1.函数调用
实验环境:Ubuntu 16.04 with x86
测试代码
int sub(int x,int y)
{
int u,v;
u = 4;v = 5;
return x+y+u+v;
}
int main()
{
int a,b,c;
a = 1;b = 2;c = 3;
c = sub(a,b);
printf("c = %d\n",c);
}
编译运行
gcc -g main.c sub.c -o sub32 -m32
测试代码汇编
main.s
.file "main.c"
.section .rodata
.LC0:
.string "c = %d\n"
.text
.globl main
.type main, @function
main:
.LFB0:
.cfi_startproc
pushq %rbp
.cfi_def_cfa_offset 16
.cfi_offset 6, -16
movq %rsp, %rbp
.cfi_def_cfa_register 6
subq $16, %rsp
movl $1, -12(%rbp)
movl $2, -8(%rbp)
movl $3, -4(%rbp)
movl -8(%rbp), %edx
movl -12(%rbp), %eax
movl %edx, %esi
movl %eax, %edi
movl $0, %eax
call sub
movl %eax, -4(%rbp)
movl -4(%rbp), %eax
movl %eax, %esi
movl $.LC0, %edi
movl $0, %eax
call printf
movl $0, %eax
leave
.cfi_def_cfa 7, 8
ret
.cfi_endproc
.LFE0:
.size main, .-main
.ident "GCC: (Ubuntu 5.4.0-6ubuntu1~16.04.12) 5.4.0 20160609"
.section .note.GNU-stack,"",@progbits
sub.s
.file "sub.c"
.text
.globl sub
.type sub, @function
sub:
.LFB0:
.cfi_startproc
pushq %rbp
.cfi_def_cfa_offset 16
.cfi_offset 6, -16
movq %rsp, %rbp
.cfi_def_cfa_register 6
movl %edi, -20(%rbp)
movl %esi, -24(%rbp)
movl $4, -8(%rbp)
movl $5, -4(%rbp)
movl -20(%rbp), %edx
movl -24(%rbp), %eax
addl %eax, %edx
movl -8(%rbp), %eax
addl %eax, %edx
movl -4(%rbp), %eax
addl %edx, %eax
popq %rbp
.cfi_def_cfa 7, 8
ret
.cfi_endproc
.LFE0:
.size sub, .-sub
.ident "GCC: (Ubuntu 5.4.0-6ubuntu1~16.04.12) 5.4.0 20160609"
.section .note.GNU-stack,"",@progbits
使用GDB调试器查看堆栈内容
gdb sub32
b main (设断点)
r (运行程序)
disas (反汇编)
i r (打印寄存器信息)
a,b,c 压栈
u,v 压栈
2.long jump
测试代码
#include <stdio.h>
#include <setjmp.h>
jmp_buf env;
int main()
{
int r,a=100;
printf("call setjmp to save environment\n");
if ((r = setjmp(env)) == 0)
{
A();
printf("normal return\n");
}
else
printf("back to main() via long jump, r = %d a = %d\n",r,a);
}
int A()
{
printf("enter A()\n");
B();
printf("exit A()\n");
}
int B()
{
printf("enter B()\n");
printf("long jump? (y|n) ");
if(getchar()=='y')
longjmp(env,1234);
printf("exit B()\n");
}
编译运行
gcc -g longjump.c -o jump32 -m32
测试代码汇编
.file "longjump.c"
.comm env,200,32
.section .rodata
.align 8
.LC0:
.string "call setjmp to save environment"
.LC1:
.string "normal return"
.align 8
.LC2:
.string "back to main() via long jump, r = %d a = %d\n"
.text
.globl main
.type main, @function
main:
.LFB0:
.cfi_startproc
pushq %rbp
.cfi_def_cfa_offset 16
.cfi_offset 6, -16
movq %rsp, %rbp
.cfi_def_cfa_register 6
subq $16, %rsp
movl $100, -8(%rbp)
movl $.LC0, %edi
call puts
movl $env, %edi
call _setjmp
movl %eax, -4(%rbp)
cmpl $0, -4(%rbp)
jne .L6
movl $0, %eax
call A
movl $.LC1, %edi
call puts
jmp .L4
.L6:
movl -8(%rbp), %edx
movl -4(%rbp), %eax
movl %eax, %esi
movl $.LC2, %edi
movl $0, %eax
call printf
.L4:
movl $0, %eax
leave
.cfi_def_cfa 7, 8
ret
.cfi_endproc
.LFE0:
.size main, .-main
.section .rodata
.LC3:
.string "enter A()"
.LC4:
.string "exit A()"
.text
.globl A
.type A, @function
A:
.LFB1:
.cfi_startproc
pushq %rbp
.cfi_def_cfa_offset 16
.cfi_offset 6, -16
movq %rsp, %rbp
.cfi_def_cfa_register 6
movl $.LC3, %edi
call puts
movl $0, %eax
call B
movl $.LC4, %edi
call puts
nop
popq %rbp
.cfi_def_cfa 7, 8
ret
.cfi_endproc
.LFE1:
.size A, .-A
.section .rodata
.LC5:
.string "enter B()"
.LC6:
.string "long jump? (y|n) "
.LC7:
.string "exit B()"
.text
.globl B
.type B, @function
B:
.LFB2:
.cfi_startproc
pushq %rbp
.cfi_def_cfa_offset 16
.cfi_offset 6, -16
movq %rsp, %rbp
.cfi_def_cfa_register 6
movl $.LC5, %edi
call puts
movl $.LC6, %edi
movl $0, %eax
call printf
call getchar
cmpl $121, %eax
jne .L9
movl $1234, %esi
movl $env, %edi
call longjmp
.L9:
movl $.LC7, %edi
call puts
nop
popq %rbp
.cfi_def_cfa 7, 8
ret
.cfi_endproc
.LFE2:
.size B, .-B
.ident "GCC: (Ubuntu 5.4.0-6ubuntu1~16.04.12) 5.4.0 20160609"
.section .note.GNU-stack,"",@progbits
使用 GDB 调试器查看堆栈内容
0x080484db <+0>: lea 0x4(%esp),%ecx
0x080484df <+4>: and $0xfffffff0,%esp
0x080484e2 <+7>: pushl -0x4(%ecx)
0x080484e5 <+10>: push %ebp
0x080484e6 <+11>: mov %esp,%ebp
0x080484e8 <+13>: push %ecx
0x080484e9 <+14>: sub $0x14,%esp
=> 0x080484ec <+17>: movl $0x64,-0x10(%ebp)
0x080484f3 <+24>: sub $0xc,%esp
0x080484f6 <+27>: push $0x8048660
0x080484fb <+32>: call 0x80483b0 <puts@plt>
0x08048500 <+37>: add $0x10,%esp
0x08048503 <+40>: sub $0xc,%esp
0x08048506 <+43>: push $0x804a060
0x0804850b <+48>: call 0x8048390 <_setjmp@plt>
0x08048510 <+53>: add $0x10,%esp
0x08048513 <+56>: mov %eax,-0xc(%ebp)
0x08048516 <+59>: cmpl $0x0,-0xc(%ebp)
0x0804851a <+63>: jne 0x8048533 <main+88>
0x0804851c <+65>: call 0x8048556 <A>
0x08048521 <+70>: sub $0xc,%esp
0x08048524 <+73>: push $0x8048680
0x08048529 <+78>: call 0x80483b0 <puts@plt>
0x0804852e <+83>: add $0x10,%esp
0x08048531 <+86>: jmp 0x8048549 <main+110>
0x08048533 <+88>: sub $0x4,%esp
0x08048536 <+91>: pushl -0x10(%ebp)
0x08048539 <+94>: pushl -0xc(%ebp)
0x0804853c <+97>: push $0x8048690
0x08048541 <+102>: call 0x8048370 <printf@plt>
0x08048546 <+107>: add $0x10,%esp
0x08048549 <+110>: mov $0x0,%eax
0x0804854e <+115>: mov -0x4(%ebp),%ecx
0x08048551 <+118>: leave
0x08048552 <+119>: lea -0x4(%ecx),%esp
0x08048555 <+122>: ret
3. 64位gcc堆栈使用情况
测试代码
#include <stdio.h>
int sub(int a, int b, int c, int d, int e, int f, int g, int h)
{
int u, v, w;
u = 9;
v = 10;
w= 11;
return a+g+u+v;
}
int main()
{
int a, b, c, d, e,f, g, h,i;
a = 1;
b = 2;
c = 3;
d = 4;
e = 5;
f = 6;
g = 7;
h = 8;
i = sub(a,b,c,d,e,f,g,h);
}
编译运行
gdb查看堆栈情况
测试代码汇编
.file "gcc64.c"
.text
.globl sub
.type sub, @function
sub:
.LFB0:
.cfi_startproc
pushq %rbp
.cfi_def_cfa_offset 16
.cfi_offset 6, -16
movq %rsp, %rbp
.cfi_def_cfa_register 6
movl %edi, -20(%rbp)
movl %esi, -24(%rbp)
movl %edx, -28(%rbp)
movl %ecx, -32(%rbp)
movl %r8d, -36(%rbp)
movl %r9d, -40(%rbp)
movl $9, -12(%rbp)
movl $10, -8(%rbp)
movl $11, -4(%rbp)
movl -20(%rbp), %edx
movl 16(%rbp), %eax
addl %eax, %edx
movl -12(%rbp), %eax
addl %eax, %edx
movl -8(%rbp), %eax
addl %edx, %eax
popq %rbp
.cfi_def_cfa 7, 8
ret
.cfi_endproc
.LFE0:
.size sub, .-sub
.globl main
.type main, @function
main:
.LFB1:
.cfi_startproc
pushq %rbp
.cfi_def_cfa_offset 16
.cfi_offset 6, -16
movq %rsp, %rbp
.cfi_def_cfa_register 6
subq $48, %rsp
movl $1, -36(%rbp)
movl $2, -32(%rbp)
movl $3, -28(%rbp)
movl $4, -24(%rbp)
movl $5, -20(%rbp)
movl $6, -16(%rbp)
movl $7, -12(%rbp)
movl $8, -8(%rbp)
movl -16(%rbp), %r9d
movl -20(%rbp), %r8d
movl -24(%rbp), %ecx
movl -28(%rbp), %edx
movl -32(%rbp), %esi
movl -36(%rbp), %eax
movl -8(%rbp), %edi
pushq %rdi
movl -12(%rbp), %edi
pushq %rdi
movl %eax, %edi
call sub
addq $16, %rsp
movl %eax, -4(%rbp)
movl $0, %eax
leave
.cfi_def_cfa 7, 8
ret
.cfi_endproc
.LFE1:
.size main, .-main
.ident "GCC: (Ubuntu 5.4.0-6ubuntu1~16.04.12) 5.4.0 20160609"
.section .note.GNU-stack,"",@progbits
二、在openeuler with arm64 中重现实践
环境 OpenEuler with arm64
- sub
测试运行
汇编
main.s
.arch armv8-a
.file "main.c"
.text
.section .rodata
.align 3
.LC0:
.string "c = %d\n"
.text
.align 2
.global main
.type main, %function
main:
.LFB0:
.cfi_startproc
stp x29, x30, [sp, -32]!
.cfi_def_cfa_offset 32
.cfi_offset 29, -32
.cfi_offset 30, -24
add x29, sp, 0
.cfi_def_cfa_register 29
mov w0, 1
str w0, [x29, 28]
mov w0, 2
str w0, [x29, 24]
mov w0, 3
str w0, [x29, 20]
ldr w1, [x29, 24]
ldr w0, [x29, 28]
bl sub
str w0, [x29, 20]
adrp x0, .LC0
add x0, x0, :lo12:.LC0
ldr w1, [x29, 20]
bl printf
mov w0, 0
ldp x29, x30, [sp], 32
.cfi_restore 30
.cfi_restore 29
.cfi_def_cfa 31, 0
ret
.cfi_endproc
.LFE0:
.size main, .-main
.ident "GCC: (GNU) 7.3.0"
.section .note.GNU-stack,"",@progbits
sub.s
.arch armv8-a
.file "sub.c"
.text
.align 2
.global sub
.type sub, %function
sub:
.LFB0:
.cfi_startproc
sub sp, sp, #32
.cfi_def_cfa_offset 32
str w0, [sp, 12]
str w1, [sp, 8]
mov w0, 4
str w0, [sp, 28]
mov w0, 5
str w0, [sp, 24]
ldr w1, [sp, 12]
ldr w0, [sp, 8]
add w1, w1, w0
ldr w0, [sp, 28]
add w1, w1, w0
ldr w0, [sp, 24]
add w0, w1, w0
add sp, sp, 32
.cfi_def_cfa_offset 0
ret
.cfi_endproc
.LFE0:
.size sub, .-sub
.ident "GCC: (GNU) 7.3.0"
.section .note.GNU-stack,"",@progbits
- longjump
测试运行
汇编
.arch armv8-a
.file "longjump.c"
.text
.comm env,312,8
.section .rodata
.align 3
.LC0:
.string "call setjmp to save environment"
.align 3
.LC1:
.string "normal return"
.align 3
.LC2:
.string "back to main() via long jump, r = %d a = %d\n"
.text
.align 2
.global main
.type main, %function
main:
.LFB0:
.cfi_startproc
stp x29, x30, [sp, -32]!
.cfi_def_cfa_offset 32
.cfi_offset 29, -32
.cfi_offset 30, -24
add x29, sp, 0
.cfi_def_cfa_register 29
mov w0, 100
str w0, [x29, 28]
adrp x0, .LC0
add x0, x0, :lo12:.LC0
bl puts
adrp x0, env
add x0, x0, :lo12:env
bl _setjmp
str w0, [x29, 24]
ldr w0, [x29, 24]
cmp w0, 0
bne .L3
bl A
adrp x0, .LC1
add x0, x0, :lo12:.LC1
bl puts
b .L4
.L3:
adrp x0, .LC2
add x0, x0, :lo12:.LC2
ldr w2, [x29, 28]
ldr w1, [x29, 24]
bl printf
.L4:
mov w0, 0
ldp x29, x30, [sp], 32
.cfi_restore 30
.cfi_restore 29
.cfi_def_cfa 31, 0
ret
.cfi_endproc
.LFE0:
.size main, .-main
.section .rodata
.align 3
.LC3:
.string "enter A()"
.align 3
.LC4:
.string "exit A()"
.text
.align 2
.global A
.type A, %function
A:
.LFB1:
.cfi_startproc
stp x29, x30, [sp, -16]!
.cfi_def_cfa_offset 16
.cfi_offset 29, -16
.cfi_offset 30, -8
add x29, sp, 0
.cfi_def_cfa_register 29
adrp x0, .LC3
add x0, x0, :lo12:.LC3
bl puts
bl B
adrp x0, .LC4
add x0, x0, :lo12:.LC4
bl puts
nop
ldp x29, x30, [sp], 16
.cfi_restore 30
.cfi_restore 29
.cfi_def_cfa 31, 0
ret
.cfi_endproc
.LFE1:
.size A, .-A
.section .rodata
.align 3
.LC5:
.string "enter B()"
.align 3
.LC6:
.string "long jump? (y|n) "
.align 3
.LC7:
.string "exit B()"
.text
.align 2
.global B
.type B, %function
B:
.LFB2:
.cfi_startproc
stp x29, x30, [sp, -16]!
.cfi_def_cfa_offset 16
.cfi_offset 29, -16
.cfi_offset 30, -8
add x29, sp, 0
.cfi_def_cfa_register 29
adrp x0, .LC5
add x0, x0, :lo12:.LC5
bl puts
adrp x0, .LC6
add x0, x0, :lo12:.LC6
bl printf
bl getchar
cmp w0, 121
bne .L8
adrp x0, env
add x0, x0, :lo12:env
mov w1, 1234
bl longjmp
.L8:
adrp x0, .LC7
add x0, x0, :lo12:.LC7
bl puts
nop
ldp x29, x30, [sp], 16
.cfi_restore 30
.cfi_restore 29
.cfi_def_cfa 31, 0
ret
.cfi_endproc
.LFE2:
.size B, .-B
.ident "GCC: (GNU) 7.3.0"
.section .note.GNU-stack,"",@progbits
- gcc64
测试运行
汇编
.arch armv8-a
.file "gcc64.c"
.text
.align 2
.global sub
.type sub, %function
sub:
.LFB0:
.cfi_startproc
sub sp, sp, #48
.cfi_def_cfa_offset 48
str w0, [sp, 28]
str w1, [sp, 24]
str w2, [sp, 20]
str w3, [sp, 16]
str w4, [sp, 12]
str w5, [sp, 8]
str w6, [sp, 4]
str w7, [sp]
mov w0, 9
str w0, [sp, 44]
mov w0, 10
str w0, [sp, 40]
mov w0, 11
str w0, [sp, 36]
ldr w1, [sp, 28]
ldr w0, [sp, 4]
add w1, w1, w0
ldr w0, [sp, 44]
add w1, w1, w0
ldr w0, [sp, 40]
add w0, w1, w0
add sp, sp, 48
.cfi_def_cfa_offset 0
ret
.cfi_endproc
.LFE0:
.size sub, .-sub
.align 2
.global main
.type main, %function
main:
.LFB1:
.cfi_startproc
stp x29, x30, [sp, -64]!
.cfi_def_cfa_offset 64
.cfi_offset 29, -64
.cfi_offset 30, -56
add x29, sp, 0
.cfi_def_cfa_register 29
mov w0, 1
str w0, [x29, 60]
mov w0, 2
str w0, [x29, 56]
mov w0, 3
str w0, [x29, 52]
mov w0, 4
str w0, [x29, 48]
mov w0, 5
str w0, [x29, 44]
mov w0, 6
str w0, [x29, 40]
mov w0, 7
str w0, [x29, 36]
mov w0, 8
str w0, [x29, 32]
ldr w7, [x29, 32]
ldr w6, [x29, 36]
ldr w5, [x29, 40]
ldr w4, [x29, 44]
ldr w3, [x29, 48]
ldr w2, [x29, 52]
ldr w1, [x29, 56]
ldr w0, [x29, 60]
bl sub
str w0, [x29, 28]
mov w0, 0
ldp x29, x30, [sp], 64
.cfi_restore 30
.cfi_restore 29
.cfi_def_cfa 31, 0
ret
.cfi_endproc
.LFE1:
.size main, .-main
.ident "GCC: (GNU) 7.3.0"
.section .note.GNU-stack,"",@progbits