2017-2018-1 20155216 《信息安全系统设计基础》第八周学习总结

2017-2018-1 20155216 《信息安全系统设计基础》第八周学习总结

课上未提交内容补充

第八周测试-2

把第一个练习中的代码在X86-64(Ubuntu)中反汇编,给出汇编代码和机器码的截图

把X86-64汇编翻译成Y86-64汇编,并给出相应机器码的截图(使用附件中的Y86-64模拟器)

C语言代码:

#include <stdlib.h>  
#include <stdio.h> 
 
int main(int argc,char *argv[])  
{  
    int i,sum=0;  
    for(i=0;i<argc;i++)  
    {  
        sum+=atoi(argv[i]);  
    }  
    printf("Total: %d\n",sum);  
    return 0;  
}

X86-64汇编:

	.file	"sum.c"

	.section	.rodata

.LC0:

	.string	"Total: %d\n"

	.text

	.globl	main

	.type	main, @function

main:

.LFB2:

	.cfi_startproc

	pushq	%rbp

	.cfi_def_cfa_offset 16

	.cfi_offset 6, -16

	movq	%rsp, %rbp

	.cfi_def_cfa_register 6

	subq	$32, %rsp

	movl	%edi, -20(%rbp)

	movq	%rsi, -32(%rbp)

	movl	$0, -4(%rbp)

	movl	$0, -8(%rbp)

	jmp	.L2

.L3:

	movl	-8(%rbp), %eax

	cltq

	leaq	0(,%rax,8), %rdx

	movq	-32(%rbp), %rax

	addq	%rdx, %rax

	movq	(%rax), %rax

	movq	%rax, %rdi

	call	atoi

	addl	%eax, -4(%rbp)

	addl	$1, -8(%rbp)

.L2:

	movl	-8(%rbp), %eax

	cmpl	-20(%rbp), %eax

	jl	.L3

	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

.LFE2:

	.size	main, .-main

	.ident	"GCC: (Ubuntu 5.4.0-6ubuntu1~16.04.4) 5.4.0 20160609"

	.section	.note.GNU-stack,"",@progbits

X86-64机器码:

0000000000000000 <main>:
   0:	55                   	push   %rbp
   1:	48 89 e5             	mov    %rsp,%rbp
   4:	48 83 ec 20          	sub    $0x20,%rsp
   8:	89 7d ec             	mov    %edi,-0x14(%rbp)
   b:	48 89 75 e0          	mov    %rsi,-0x20(%rbp)
   f:	c7 45 fc 00 00 00 00 	movl   $0x0,-0x4(%rbp)
  16:	c7 45 f8 00 00 00 00 	movl   $0x0,-0x8(%rbp)
  1d:	eb 26                	jmp    45 <main+0x45>
  1f:	8b 45 f8             	mov    -0x8(%rbp),%eax
  22:	48 98                	cltq   
  24:	48 8d 14 c5 00 00 00 	lea    0x0(,%rax,8),%rdx
  2b:	00 
  2c:	48 8b 45 e0          	mov    -0x20(%rbp),%rax
  30:	48 01 d0             	add    %rdx,%rax
  33:	48 8b 00             	mov    (%rax),%rax
  36:	48 89 c7             	mov    %rax,%rdi
  39:	e8 00 00 00 00       	callq  3e <main+0x3e>
  3e:	01 45 fc             	add    %eax,-0x4(%rbp)
  41:	83 45 f8 01          	addl   $0x1,-0x8(%rbp)
  45:	8b 45 f8             	mov    -0x8(%rbp),%eax
  48:	3b 45 ec             	cmp    -0x14(%rbp),%eax
  4b:	7c d2                	jl     1f <main+0x1f>
  4d:	8b 45 fc             	mov    -0x4(%rbp),%eax
  50:	89 c6                	mov    %eax,%esi
  52:	bf 00 00 00 00       	mov    $0x0,%edi
  57:	b8 00 00 00 00       	mov    $0x0,%eax
  5c:	e8 00 00 00 00       	callq  61 <main+0x61>
  61:	b8 00 00 00 00       	mov    $0x0,%eax
  66:	c9                   	leaveq 
  67:	c3                   	retq

Y86-64汇编:

	.file	"sum.c"

	.section	.rodata

.LC0:

	.string	"Total: %d\n"

	.text

	.globl	main

	.type	main, @function

main:

.LFB2:

	.cfi_startproc

	pushq	%rbp

	.cfi_def_cfa_offset 16

	.cfi_offset 6, -16

	movq	%rsp, %rbp

	.cfi_def_cfa_register 6

	subq	$32, %rsp

	irmovq	%edi, -20(%rbp)

	irmovq	%rsi, -32(%rbp)

	irmovlq	$0, -4(%rbp)

	irmovlq	$0, -8(%rbp)

	jmp	.L2

.L3:

	movl	-8(%rbp), %eax

	cltq

	leaq	0(,%rax,8), %rdx

	movq	-32(%rbp), %rax

	addq	%rdx, %rax

	movq	(%rax), %rax

	movq	%rax, %rdi

	call	atoi

	addl	%eax, -4(%rbp)

	addl	$1, -8(%rbp)

.L2:

	movlq	-8(%rbp), %eax

	cmpl	-20(%rbp), %eax

	jl	.L3

	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

.LFE2:

	.size	main, .-main

	.ident	"GCC: (Ubuntu 5.4.0-6ubuntu1~16.04.4) 5.4.0 20160609"

	.section	.note.GNU-stack,"",@progbits

第八周测试-3

基于socket 使用教材的csapp.h csapp.c,实现daytime(13)服务器(端口我们使用13+后三位学号)和客户端
服务器响应消息格式是

客户端IP:XXXX
服务器实现者学号:XXXXXXXX
当前时间: XX:XX:XX

上方提交代码

提交一个客户端至少查询三次时间的截图测试截图

提交至少两个客户端查询时间的截图测试截图

基于socket,用多进程和多线程分别实现daytime服务器并发功能。

详情查看我的博客:

第八周课下作业2

教材学习内容总结

一、三种并发的方式:进程、线程、I/O多路复用

进程:

进程(Process)是计算机中的程序关于某数据集合上的一次运行活动,是系统进行资源分配和调度的基本单位,是操作系统结构的基础。在早期面向进程设计的计算机结构中,进程是程序的基本执行实体;在当代面向线程设计的计算机结构中,进程是线程的容器。程序是指令、数据及其组织形式的描述,进程是程序的实体。

进程的定义:

狭义定义:进程就是程序的执行过程。

进程是一个具有一定独立功能的程序关于某个数据集合的一次运行活动。它是操作系统动态执行的基本单元,在传统的操作系统中,进程既是基本的分配单元,也是基本的执行单元。

主要特征:

动态性:进程的实质是程序在多道程序系统中的一次执行过程,进程是动态产生,动态消亡的。

并发性:任何进程都可以同其他进程一起并发执行

独立性:进程是一个能独立运行的基本单位,同时也是系统分配资源和调度的独立单位;

异步性:由于进程间的相互制约,使进程具有执行的间断性,即进程按各自独立的、不可预知的速度向前推进

结构特征:进程由程序、数据和进程控制块三部分组成。

多个不同的进程可以包含相同的程序:一个程序在不同的数据集里就构成不同的进程,能得到不同的结果;但是执行过程中,程序不能发生改变。

调度算法

FIFO(First Input First Output 先进先出法)、

RR(时间片轮转算法)、

(HPF)最高优先级算法。

线程

定义:

线程是程序中一个单一的顺序控制流程。进程内一个相对独立的、可调度的执行单元,是系统独立调度和分派CPU的基本单位指运行中的程序的调度单位。在单个程序中同时运行多个线程完成不同的工作,称为多线程。

两个基本类型:

用户级线程:管理过程全部由用户程序完成,操作系统内核心只对进程进行管理。

系统级线程(核心级线程):由操作系统内核进行管理。操作系统内核给应用程序提供相应的系统调用和应用程序接口API,以使用户程序可以创建、执行、撤消线程。

线程与进程的区别:

1)地址空间和其它资源(如打开文件):进程间相互独立,同一进程的各线程间共享。某进程内的线程在其它进程不可见。

2)通信:进程间通信IPC,线程间可以直接读写进程数据段(如全局变量)来进行通信——需要进程同步和互斥手段的辅助,以保证数据的一致性。

3)调度和切换:线程上下文切换比进程上下文切换要快得多。

4)在多线程OS中,进程不是一个可执行的实体。

I/O多路复用

通过I/O多路复用技术,系统内核缓冲I/O数据,当某个I/O准备好后,系统通知应用程序该I/O可读或可写,这样应用程序可以马上完成相应的I/O操作,而不需要等待系统完成相应I/O操作,从而应用程序不必因等待I/O操作而阻塞。

与多进程和多线程技术相比,I/O多路复用技术的最大优势是系统开销小,系统不必创建进程/线程,也不必维护这些进程/线程,从而大大减小了系统的开销。

I/O复用典型的应用:

(1)当客户处理多个描述字时(一般是交互式输入和网络套接口),必须使用I/O复用。

(2)当一个客户同时处理多个套接口时,而这种情况是可能的,但很少出现。

(3)如果一个TCP服务器既要处理监听套接口,又要处理已连接套接口,一般也要用到I/O复用。

(4)如果一个服务器即要处理TCP,又要处理UDP,一般要使用I/O复用。

(5)如果一个服务器要处理多个服务或多个协议,一般要使用I/O复用。

二、线程控制及相关系统调用

在用户空间中实现线程

线程在操作系统内核中实现

混合模式

三、线程同步互斥相关系统调用

初始化:

在Linux下, 线程的互斥量数据类型是pthread_mutex_t. 在使用前, 要对它进行初始化:

对于静态分配的互斥量, 可以把它设置为PTHREAD_MUTEX_INITIALIZER, 或者调用pthread_mutex_init。

对于动态分配的互斥量, 在申请内存(malloc)之后, 通过pthread_mutex_init进行初始化, 并且在释放内存(free)前需要调用pthread_mutex_destroy。

返回值:成功则返回0, 出错则返回错误编号。

说明:如果使用默认的属性初始化互斥量, 只需把attr设为NULL。

死锁:

死锁主要发生在有多个依赖锁存在时,会在一个线程试图以与另一个线程相反顺序锁住互斥量时发生。如何避免死锁是使用互斥量应该格外注意的东西。

总体来讲, 有几个基本原则:

对共享资源操作前一定要获得锁。

完成操作以后一定要释放锁。

尽量短时间地占用锁。

如果有多锁,如获得顺序是ABC连环扣,释放顺序也应该是ABC。

线程错误返回时应该释放它所获得的锁。

在编译中要加 -lpthread参数。

教材学习中的问题和解决过程

PID有什么作用或意义

  • 问题1解决方案:

PID就是各进程的身份标识,程序一运行系统就会自动分配给进程一个独一无二的PID。进程中止后PID被系统回收,可能会被继续分配给新运行的程序。

PID一列代表了各进程的进程ID,也就是说,PID就是各进程的身份标识。

只要运行一程序,系统会自动分配一个标识。

是暂时唯一:进程中止后,这个号码就会被回收,并可能被分配给另一个新进程。

只要没有成功运行其他程序,这个pid会继续分配给当前要运行的程序。

如果成功运行一个程序,然后再运行别的程序时,系统会自动分配另一个pid。

代码调试中的问题和解决过程

  • 问题1:

这是一个查看父子进程PID的代码

#include <stdio.h> 

main() 

{ 

 int pid; 

 pid = getpid(); 

 printf("my pid is %d\n", pid); 

 pid = getppid(); 

 printf("my parent’s pid is %d\n", pid); 

 sleep(40); 

} 

运行结果:

父进程和子进程的PID有什么联系

  • 问题1解决方案:

父进程和子进程的关系是子进程是父进程的一个副本,创建子进程后,子进程会有自己的空间,然后把父进程的数据拷贝到子进程的空间里。

运行时,谁先运行是不确定的,由系统决定。

若连续创建进程,PID是连续的。

代码托管

结对及互评

本周结对学习情况

- [20155214](http://www.cnblogs.com/besti155214/p/7782336.html)
- 结对照片
- 结对学习内容
    - 多进程与多线程的daytime服务器实现。
    - 第四章家庭作业。

其他(感悟、思考等,可选)

1、使用多进程和多线程可大大提高代码的运行效率。

2、线程可以在操作系统和用户空间中混合调用。

学习进度条

代码行数(新增/累积) 博客量(新增/累积) 学习时间(新增/累积) 重要成长
目标 5000行 30篇 400小时
第三周 114/114 3/3 20/20
第四周 136/250 2/5 18/38
第五周 87/337 2/7 22/60
第六周 271/608 2/9 30/90
第七周 185/716 2/11 30/90
第八周 531/1247 3/14 30/90

尝试一下记录「计划学习时间」和「实际学习时间」,到期末看看能不能改进自己的计划能力。这个工作学习中很重要,也很有用。
耗时估计的公式
:Y=X+X/N ,Y=X-X/N,训练次数多了,X、Y就接近了。

参考:软件工程软件的估计为什么这么难软件工程 估计方法

  • 计划学习时间:25小时

  • 实际学习时间:20小时

  • 改进情况:

(有空多看看现代软件工程 课件
软件工程师能力自我评价表
)

参考资料

posted @ 2017-11-11 19:22  Lee.X  阅读(299)  评论(0编辑  收藏  举报