dasqweq L18 2020-02-20 10:42:51 lab0:Coding!
909 0

“操作系统实验-基于uCore OS(厦门大学)”实验报告

lab0:Coding!

操作系统实验报告

实验零 lab0

系别:网络空间安全系

实验者姓名:吴名

学号:22920172204233

目录

一、实验目的

二、实验内容

三、实验练习

1: 了解汇编

2: 用gdb调试

3: 掌握指针和类型转换相关的C编程

4: 掌握通用链表结构相关的C编程

四、实验总结

一、实验目的


​ 了解操作系统开发实验环境,熟悉命令行方式的编译、调试工程,掌握基于硬件模拟器的调试技术,熟悉C语言编程和指针的概念,了解X86汇编语言。

二、实验内容


​ 1: 了解汇编;2: 用gdb调试;3: 掌握指针和类型转换相关的C编程;4: 掌握通用链表结构相关的C编程

三、实验练习


1: 了解汇编

运行 gcc -S -m32 lab0_ex1.c 生成 .s的汇编语言文件

  • -S表示仅仅编译不生成链接或者汇编
  • -m32表示生成 32位机器的汇编代码

得到 lab_ex1.s 汇编文件

​ 对比汇编文件 与 C语言文件

copy

​ 由实验指导书可知

​ GCC扩展内联汇编的基本格式是:

asm [volatile] ( Assembler Template

: Output Operands

[ : Input Operands

[ : Clobbers ] ])

​ 在输入部分没有 " = " 因此上面的C语言代码是用于将数据存入寄存器的代码

​ 因此得到的主要汇编代码应该为:(以下为 lab_ex1.s 汇编文件的代码)

    .file    "lab0_ex1.c"
    .globl    count
    .data
    .align 4
    .type    count, @object
    .size    count, 4
count:
    .long    1
    .globl    value
    .align 4
    .type    value, @object
    .size    value, 4
value:
    .long    1
    .comm    buf,40,32
    .text
    .globl    main
    .type    main, @function
main:
.LFB0:
    .cfi_startproc
    pushl    %ebp
    .cfi_def_cfa_offset 8
    .cfi_offset 5, -8
    movl    %esp, %ebp
    .cfi_def_cfa_register 5
    pushl    %edi
    pushl    %ebx
    .cfi_offset 7, -12
    .cfi_offset 3, -16
    movl    count, %edx ;1
    movl    value, %eax ;2
    movl    buf, %ebx ;3 这三行与上文所说的C语言代码相吻合
    movl    %edx, %ecx
    movl    %ebx, %edi
#APP
# 6 "lab0_ex1.c" 1
    cld ;1
    rep ;2
    stosl ;3 这三行与上文所说的C语言代码相吻合
# 0 "" 2
#NO_APP
    popl    %ebx
    .cfi_restore 3
    popl    %edi
    .cfi_restore 7
    popl    %ebp
    .cfi_restore 5
    .cfi_def_cfa 4, 4
    ret
    .cfi_endproc
.LFE0:
    .size    main, .-main
    .ident    "GCC: (Ubuntu 4.8.2-19ubuntu1) 4.8.2"
    .section    .note.GNU-stack,"",@progbits
copy

​ 可见通过运行C语言代码,实现了将C语言这种高级语言向汇编代码的转变,为后续的操作系统试验打下基础,实际了解和操作了将高级语言向低级语言转换的过程。

2: 用gdb调试

在控制台输入:

$cd ucore_lab/related_info/lab0

$gcc -g -m32 lab0_ex2.c

文件夹得到文件 a.out

控制台运行 ./a.out

在控制台得到输出 Hello,world!

继续深入实验,在 lab0_ex2.c C语言文件的每行代码设置断点进行观察:

控制台输入:

$gcc -g -m32 lab0_ex2.c -o lab0_ex2

$gdb lab0_ex2

(gdb)b1>(gdb) b 1 ---> (gdb) b 7

$(gdb) info breakpoints

最后得到运行结果

1       breakpoint     keep y   0x08048426 in main at lab0_ex2.c:1
2       breakpoint     keep y   0x08048426 in main at lab0_ex2.c:2
3       breakpoint     keep y   0x08048426 in main at lab0_ex2.c:3
4       breakpoint     keep y   0x08048426 in main at lab0_ex2.c:4
5       breakpoint     keep y   0x08048426 in main at lab0_ex2.c:5
6       breakpoint     keep y   0x08048432 in main at lab0_ex2.c:6
7       breakpoint     keep y   0x08048437 in main at lab0_ex2.c:7
copy

​ 可以发现直到第五行这段代码所分配的地址实际上是不变的,即直到 printf 出现以后才出现了内存上的变化,因此可以推断应该是在 printf 介入以后才在汇编语言中产生了内存的调用等活动,才会有内存的分配问题。通过这个练习了解了gdb调试的方法。

3: 掌握指针和类型转换相关的C编程

运行 gcc - g -m32 lab0_ex3.c 2>&1|tee make.log

错误报告存在 make.log 里面

lab0_ex3.c代码:

copy

发现报错

warning: format ‘%llx’ expects argument of type ‘long long unsigned int’, but argument 2 has type ‘struct gatedesc’
copy

由此可以判断是由于 gintr 的类型为所定义的结构体 gatedesc 所导致的类型不匹配无法输出,因此我们只需在输出的时候进行强制类型转化。

对 lab0_ex3.c 文件进行修改:

copy

得到输出

intr is 0x10002
gintr is 0xee0000010002
copy

对代码进行分析:

通过调用 SETGATE 这个宏对 gintr 进行赋值

copy

将值代入下面式子,每行的结果计算于注释处

copy

从高位到低位组合起来,依次是 0x0000 ee00 0001 0002

因此 intr 应该输出 0x10002 ; gintr 应该输出 0xee00 0001 0002

copy

继续回答问题,请问执行上述指令后, intr的值是多少?

因此对 lab0_ex3.c 的文件进行修改

copy

因为与前面的实验代码相似,因此可以预知的,输出应该是低32位的输出 0x10002

在控制台中输入

gcc -g -m32 lab0_ex3.c

./a.out

得到输出

0x10002
copy

与预期结果相同

​ 通过这个实验了解通过:对 long long unsigned 和 unsigned int 类型进行逐位取值的分配与确定的操作,了解到了如何进行类型转化。

4: 掌握通用链表结构相关的C编程

问题:

用在 related_info/lab0/list.h 中定义的结构和函数来实现一个小应用程序完成一个基于此链表的数据对象的访问操作。

那我们先对 list.h 文件阅读分析

copy

不难发现在此处的链表结构应该是双向循环链表结构,首位相接,有前向后向两个节点

copy

里面已经定义好了一系列的函数对链表进行操作

我同过 lab0_ex4.c 文件进行对练习四的操作与检验

copy

值得一提的是在 list.h 代码段里有一处错误需要修改

copy

调用控制台命令 gcc -g -m32 lab0_ex4.c

我们可以得到输出

8
7
6
5
4
3
2
1
copy

但这其实与我们与预期的结果不相同

通过这段代码可知

copy

因此在此链表里面尾结点并没有打印出来,因此我对 lab0_ex4.c 进行了轻微的修改

copy

在循环输出链表之前,再加一句输出,将当前节点的值进行输出,得到新的结果

9
8
7
6
5
4
3
2
1
copy

再对代码进行改进,尝试从前往后进行输出

copy

运行得到输出

9
8
7
6
5
4
3
2
1
1
2
3
4
5
6
7
8
9        
copy

​ 由此,我们得到了一个具有头节点的,双向循环链表,通过实验四我们了解了如何定义一个结构体,创建自己想要的结构类型,为以后的内存的调用打下基础,学习和了解了双向循环链表的创建过程,在debug的过程中充分体验了双向链表的地址的变化过程,通过查看双向链表的地址,了解和学习了地址的分配的过程。

四、实验总结

​ 通过本次学习了解了gdb调试的方法;通过本次学习了解通过:对 long long unsigned 和 unsigned int 类型进行逐位取值的分配与确定的操作,了解到了如何进行类型转化。我们得到了一个具有头节点的,双向循环链表,通过实验四我们了解了如何定义一个结构体,创建自己想要的结构类型,为以后的内存的调用打下基础,学习和了解了双向循环链表的创建过程,在debug的过程中充分体验了双向链表的地址的变化过程,通过查看双向链表的地址,了解和学习了地址的分配的过程。

最新评论
暂无评论~