- 博客(42)
- 资源 (36)
- 收藏
- 关注
原创 采用单链表进行冒泡排序
#include #include typedef struct Node{ struct Node *next; int num;}Node;void bubble_sort(Node* head){ Node* tail = NULL; while(tail != head->next) { Node* pre = head; Node* cur = pr
2015-03-27 20:21:16
802
原创 如何给论文添加参考文献
一、在写论文的时候,尽量一边写一边就把该引用的参考文献插入进去,免得写完之后再来全文找,再一个一个添加。但是如果论文参考文献比较多,写完以后发现需要在某处加入一个参考文献就很麻烦了,因为后面的参考文献序号都会改变,容易出错。解决这个问题的比较好的办法就是采用尾注。如果你要在某句话的后面加入参考文献,点击插入->引用->脚注和尾注,将弹出的属性对话框按如下图修改:然后点击插入按钮,光
2015-03-23 18:46:45
35710
原创 linux0.11 execve系统调用分析
在Linux平台下,我们一般都是在命令行下键入"./hello"来运行一个当前目录下的hello应用程序("./"指定当前目录)。虽然看似很简单,但这么小小的一个操作其实涉及到了很多的知识。比如:shell是如何将hello调入内存的?hello在运行前shell执行了哪些操作?hello的父进程又是哪个?回答这些问题之前我们先来看下面的一个例子:这个例子包含两个程序,第一个test_hell
2015-01-04 18:15:27
3210
原创 块设备请求项队列及硬盘驱动
linux0.11在读写块设备的时候,并不直接对块设备进行操作,而是借由低级的ll_rw_block函数通过请求项来与设备进行联系,也即加入了一个中间环节。为什么要这样做呢?当然,你也可以直接对块设备进行操作,但是直接操作会存在一些问题:1. 同一个进程在写的过程中就不能发出读的请求,反之,在读的过程中也不能发出写的请求。2. 当一个进程正在对硬盘进行写或者读的时候,其他进程就不能发出硬盘
2014-12-30 15:41:06
1438
原创 linux0.11进程睡眠sleep_on函数和唤醒wake_up函数分析
内核中的这两个函数主要用于访问资源时的同步操作,典型的例子就是高速缓冲区的访问,如果两个进程都要访问同一个缓冲块,那么其中的一个进程就必然睡眠等待,直到该缓冲块被释放才可访问。赵炯博士所著的linux0.11内核完全注释一书中也是对该问题进行详细的讨论,但是我在阅读这段代码的时候还是有些疑问,在此发表下自己的见解。首先将这两个函数贴出来:void sleep_on(struct task_
2014-12-26 15:00:26
4590
7
原创 linux0.11块设备读写过程分析
Linux将一切设备视为文件,所以对于块设备也一样。块设备常见的有软盘和硬盘两种,虽然当今的硬盘传输速率已经非常快,但还是远不及内存,所以当CPU访问这类块设备的时候需要借助一个缓冲,以求得效率的最大化。因此,在分析块设备数据传输过程前,先了解下高速缓冲区(cache)是如何工作的。Linux0.11划分内存的一部分作为cache,这部分内存从内核末端开始到4M内存处,一共可以划出3千多个逻辑
2014-12-23 13:43:38
2305
转载 为什么全局描述符表GDT的第0项总是一个空描述符
为什么全局描述符表GDT的第0项总是一个空描述符,而局部描述符表却不是这样?386的保护模式下: DT=GDT*1+IDT*1+LDT*n;IDT和每个LDT都要到GDT中报一次到.有一个描述符项与一张表对应.什么是描述表呢? 其实很简单。1个段描述表记录记录一个段的特征信息,中断描述符表记录中断的端口和其对应的函数入口地址或门的入口函数地址,全局描述表GDT记录所有表的地址。其
2014-12-21 21:26:32
1389
1
原创 Minix文件系统磁盘结构分析
00000000 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| 引导块 *00000400 40 00 a0 00 01 00 01 00 06 00 00 00 00 1c 08 10 |@...............| 超级块00000410 8f 13 01 00 00 00 00
2014-12-21 16:48:14
2672
原创 linux0.11信号处理
linux中的信号处理函数提供了对程序异步处理的功能,比如键盘按下ctrl+c键,该操作将产生一个SIGINT信号,并被发送到当前前台的进程中。内核采用一个无符号长整形变量中(32bit)的每一个比特位来表示不同的信号,因此最多可以定义32种信号。对于一个进程来说,当收到一个信号时,有3种不同的处理方式:1. 忽略该信号。其中SIGKILL和SIGSTOP不能忽略。2. 捕获该信号。调用s
2014-12-19 13:09:55
1245
1
原创 再谈分页
Linux0.11最多支持64个任务,而每个进程拥有的线性空间为64M,64*64M=4G,所以这64个任务刚好填满4G的线性空间。对于一个任务所独占的64M空间并不是说它就一定需要64M的物理内存。linux0.11设计的物理内存只有16M,除去内核以及高速缓冲区占用的4M,就只剩12M给用户进程,至于为什么拥有64M线性空间的进程能够在12M的物理内存甚至4M内存中运行,一方面原因在于通常实际
2014-12-16 15:37:09
791
原创 再谈分段
我们已经知道CPU的分段机制的作用在于将程序逻辑地址映射为线性地址,CPU在启动了保护模式之后,其段寄存器不再作为地址内容的一部分,而是作为一种称为选择子的东西,它作为在全局描述符表或者局部描述符表中寻找目标地址的索引,所以对于程序中每一个地址的寻址就需要指定两个事物,第一个就是选择子,第二个就是描述符表。选择子就是段寄存器,而描述符表就是一个全局数组变量。这个描述符表其实应该是二维的数组,第一维
2014-12-15 12:12:23
569
原创 linux0.11内核空间与用户空间数据交换
学习linux到现在对于这个问题一直都没有在意,细看代码时发现这确实是一个大问题,并且感觉很巧妙。当用户进程执行系统调用进入内核空间时,所有段都指向内核段,但是fs却除外,它需要扮演负责内核空间与用户空间数据的交换的重要角色。其中一个典型的例子就是printk函数,在内核空间中如果要打印一串数据,由于ds段指向内核空间,所以无法向用户空间的tty0控制终端输送数据,linux为了实现print
2014-12-14 20:52:07
695
原创 linux学习总结1
学习linux系统已有月余,可能是天资问题,到现在才感觉入门,不过还是对自己这段时间能够沉下心坚持学习下来感到欣慰,也该作一个阶段性的总结了。学习linux之前对于这个系统基本上是零基础,总感觉linux博大精深,我一开始不去研究它也是因为平时都是零碎的时间,感觉零碎的去学习它很难有一个比较好的学习效果。趁着找完工作这段时间,可以大量时间投入到上面去,一个月下来自己也感觉颇有收获,算是入门了吧。
2014-12-14 12:50:33
738
原创 linux0.11任务切换switch_to
#define switch_to(n) {\struct {long a,b;} __tmp; \__asm__( "cmpl %%ecx,current\n\t" \ "je 1f\n\t" \ "movw %%dx,%1\n\t" \ "xchgl %%ecx,current\n\t" \ "ljmp *%0\n\t" \ "cmpl %%ecx,last_task_used
2014-12-13 20:54:37
1766
原创 linux0.11init进程及shell原理分析
static char * argv_rc[] = { "/bin/sh", NULL };static char * envp_rc[] = { "HOME=/", NULL };static char * argv[] = { "-/bin/sh",NULL };static char * envp[] = { "HOME=/usr/root", NULL };void init(
2014-12-12 16:34:15
2510
2
原创 常用的linux命令
比如针对文件夹folder打包 tar -cvf folder.tar 解包tar -xvf folder.tar压缩gzip tar -zcvf folder.tar.gz 解压缩tar -zx
2014-12-11 15:56:39
590
转载 ubuntu下安装bochs
安装gcc编译环境sudo apt-get install build-essentialsudo apt-get install xorg-devsudo apt-get install libgtk2.0-dev下载bochs最新版本(目前为2.6.7)http://bochs.sourceforge.net/安装命令tar vxzf b
2014-12-11 15:41:36
669
原创 bochs神奇的任意断点调试
#=======================================================================# MAGIC_BREAK:# This enables the "magic breakpoint" feature when using the debugger.# The useless cpu instruction XCHG BX,
2014-12-11 15:08:14
2740
原创 linux0.11进程调度分析
10ms时钟中断 --> 时钟中断函数timer_interrupt,将jiffier加1 --> 调用do_timer函数,将当前进程counter计数减1,如果--counter大于0,则返回继续执行该任务,否则 --> 调用schedule函数,代码如下:void schedule(void){ int i,next,c; struct task_struct ** p;/*
2014-12-11 14:12:45
1597
原创 linux0.11字符设备的读写过程分析
首先要知道linux系统/dev目录下的各种设备文件(文件属性c打头)并不占用空间,你可以发现他们的大小为0字节,他们的区别在于文件的i节点的成员i_zone[0]的值不同,该值标识不同的设备号。比如tty0文件的设备号为0x0400,tty1设备号为0x0401,hd0设备号为0x0300,hd1设备号为0x0301等。而这个设备号里面又包含两部分内容:高字节标识不同类设备,比如tty0和hd0
2014-12-10 20:48:43
1733
原创 方向位DF对串操作的影响
首先看如下代码:#include struct task_struct{ int a,b,c,d,e;};int main(){ struct task_struct init={1,2,3,4,5}; struct task_struct new_task={0,0,0,0,0}; struct task_struct *task[5]={&init}; struct ta
2014-12-09 16:57:12
1214
原创 linux0.11 编译遇到的问题
在oldlinux网址下载了linux0.11能够编译通过的代码,在自己ubuntu13.10的机子上确实能够编译成功,gcc版本4.8.1,但是放在boshs上确无法运行,总结有如下问题:1. 反复Loading system... 。一步一步调试,发现当setup完后并没有进入到head中,通过查看Image二进制文件,发现第5扇区(0xa00)开始处的指令并不是head代码。经过一步一步
2014-12-09 16:08:33
1973
1
原创 分段机制
首先谈一下80X86系统中存在的三个地址概念:逻辑地址、线性地址和物理地址。逻辑地址:是指由程序产生的与段相关的偏移地址,也就是在Intel保护模式下程序执行代码段限长内的偏移地址。例如,在C语言指针编程中,读取指针变量本身的值(&操作),实际上这个值就是逻辑地址,它是相对于你当前进程数据段的地址,与绝对物理地址不相关。应用程序员仅需与逻辑地址打交道,而分段和分页机制对他们来说是透明的,仅由系
2014-12-03 19:51:35
1065
原创 一个操作系统的实现——进程
在Orange中,对于进程的实现包含以下步骤:1. 首先定义一个任务,如下类似的函数,函数名就是任务到入口地址。void TestA(){ while(1){}}2. 在kernel_main函数中初始化进程结构体,除了初始化进程的name和pid,段寄存器(注意T1位为1,LDT选择子),eip和esp之外,关键需要初始化进程的局部描述符LDT在GDT中的选择子,以便从内核跳入进程
2014-12-01 11:23:36
883
原创 socket网络编程之TCP_Client
#include #include #include #include DWORD WINAPI RecvProc( LPVOID lpParameter // thread data);struct RECVPARAM{ SOCKET sock; SOCKADDR_IN sockaddr;};void main(){ WORD wVersionRequse
2014-11-27 19:42:54
1431
原创 一只小蜜蜂!
Problem Description有一只经过训练的蜜蜂只能爬向右侧相邻的蜂房,不能反向爬行。请编程计算蜜蜂从蜂房a爬到蜂房b的可能路线数。其中,蜂房的结构如下所示。Input输入数据的第一行是一个整数N,表示测试实例的个数,然后是N 行数据,每行包含两个整数a和b(0Output对于每个测试实例,请输出蜜蜂从蜂房a爬到蜂房b的可能路线数,每个实例的输出占一行。S
2014-05-07 10:39:15
627
原创 项目那点事之OPC
这段时间实验室做一个智能监控的项目,涉及到现场多个设备的控制以及数据采集。计划采用PLC通过485总线与各个设备进行数据交互,同时增设一台工控机进行上位机操控,与PLC进行数据通信,一方面通过上位机程序对各设备进行控制,另一方面实时显示各设备的运行状态。我主要负责工控机这边上位机程序,采用LabVIEW语言编程,需要跟PLC进行通信,然后再借由PLC与现场设备进行数据交换。实验室采购的PLC型
2013-12-02 17:29:37
2766
转载 什么是OPC UA
OPC UA(Unified Architecture,统一架构)是下一代的OPC 标准,通过提供一个完整的,安全和可靠的跨平台的架构,以获取实时和历史数据和时间。OPC UA基于OPC基金会提供的新一代技术,提供安全,可靠和独立于厂商的,实现原始数据和预处理的信息从制造层级到生产计划或ERP层级的传输。通过OPC UA,所有需要的信息在任何时间,任何地点对每个授权的应用,每个授权的人员都可用
2013-12-02 17:26:57
5507
转载 什么是OPC技术
什么是OPC技术作者:未知来源:网络点击数:27307 日期:2008-5-22Q:什么是OPC技术?OPC技术是什么意思?OPC是Object Linking and Embedding(OLE)for Process Control的缩写,它是微软公司的对象链接和嵌入技术在过程控制方面的应用。由一些世界上占领先地位的自动化系统和硬件、软件公司与微软(Microsoft)紧密合作
2013-12-02 17:24:12
1573
原创 TCP/IP编程之读数据
在win32平台编写网络应用程序的时候,我们一般都采用WinSOCKET库来实现,在具体编程时,比如编写一个TCP服务器程序,采用SOCKET相关的一些API函数很容易的就能实现,并且步骤固定,首先新建一个SOCKET对象,然后绑定端口,接着监听,等待接收连接,最后收发数据,这么一个过程大多数人可能都熟记于心了,但是具体应用的时候,一些编程的细节如何没处理好的话,带来的问题可能就没有那么简单了。接
2013-11-30 11:19:12
1125
原创 处理器大小端模式
为什么会有大小端模式之分呢?这是因为在计算机系统中,我们是以字节为单位的,每个地址单元都对应着一个字节,一个字节为8bit。但是在C语言中除了8bit的char之外,还有16bit的short型,32bit的long型(要看具体的编译器),另外,对于位数大于 8位的处理器,例如16位或者32位的处理器,由于寄存器宽度大于一个字节,那么必然存在着一个如何将多个字节安排的问题。因此就导致了大端存储
2013-10-02 20:22:54
1226
原创 C语言全局变量定义与声明技巧
在实际的编程中,全局变量对我们编程来说既是喜又是泪,虽然说项目中尽量避免使用全局变量,但总有些时候不得不使用它,并且可能使用得不少,各个模块可能有含有或多或少的几个全局变量,而当别的模块需要引用的时候,就必须extern它,造成你定义了一遍又声明了一遍,这样就稍显得麻烦。下面介绍一种全局变量的管理方法,至始至终只定义一次,所有的全局变量以某种声明方式放入一个名叫global.h的头文件中,然后别的
2013-09-08 23:16:19
8682
原创 union关键字使用
union关键字的用法与struct的用法基本一致,union仅维护数据成员中占用内存最大的一个空间,也即所有数据成员将共用一个空间,同一时间只能存储其中一个数据成员,所有的成员具有相同的起始地址。比如:union Test{ char a; int b; double c;};在32位系统中sizeof(Test)的值将为8。a,b
2013-08-23 11:17:24
1401
原创 循环单向链表
typedef struct LIST{ struct LIST *Next;}LIST;/* * 初始化一个循环单向链表 */void list_init(LIST *head){ head->Next = head;}/* * 判断链表是否为空 */int is_list_empty(LIST *head){ return
2013-08-23 09:10:06
759
原创 C文件操作
#include #include #include #define Malloc(type,n) (type *)malloc((n)*sizeof(type))static char *line = NULL;static int max_line_len = 128;static char* readline(FILE *input){ int l
2013-08-03 13:02:35
861
原创 socket网络编程之TCP_Server
#include #include #include #include DWORD WINAPI RecvProc( LPVOID lpParameter // thread data);struct RECVPARAM{ SOCKET sock; SOCKADDR_IN sockaddr;};void main(){ WO
2013-07-24 21:24:23
818
原创 二叉树遍历
typedef struct _BINARY_TREE{ int data; struct _BINARY_TREE *left; struct _BINARY_TREE *right;}BINARY_TREE;二叉树的基本数据结构如上所示,下面给出以深度优先的三种方法对二叉树进行遍历的算法(递归实现)。void preOrder(BINARY_TREE *root) //先序遍历
2013-07-24 11:22:11
615
原创 函数调用时的堆栈结构分析
void func(int a, int b){ int c; c=a+b;}int main(void){ func(3,4); return 0;}编译后的汇编代码如下图所示,当然main函数也是一个调用函数,但是我们不看它,直接看调用func函数的汇编代码。从第11行开始,首先,从最后一个表格看一下压栈前的ebp和esp的值,ebp=0x001
2013-07-23 16:09:53
1300
原创 指针和指针的指针
int main(void){ int data = 5; int *pdata = &data; int **ppdata = &pdata; return 0;} 首先在VC6.0里面新建一个C++控制台工程,然后键入以上代码,最后按F10进行调试。在watch窗口中键入如上图所示变量信息,首先,对于第一行data=5没问题;然后对data变量采用取地址符&
2013-07-22 18:10:30
701
1
原创 循环双向链表
#include typedef struct _LIST{ struct _LIST *previous; struct _LIST *next;}LIST;/* * List initialization */void list_init(LIST *list_head){ list_head->next = list_head; lis
2013-07-22 15:09:23
704
C#操作OPC,包含KepServer4.5软件, OPCAutomation.dll以及一个C#工程
2014-12-20
LabVIEW与Android共享变量通信教程与软件
2014-05-17
labview操作opc教程
2013-12-02
WIN7设置WIFI热点
2013-09-08
labview 中的GPIB仪器编程
2010-08-27
智能车舵机的相关原理与控制原理
2010-05-16
空空如也
TA创建的收藏夹 TA关注的收藏夹
TA关注的人