当前位置:文档之家› 驱动程序原理

驱动程序原理

驱动程序原理
驱动程序原理

知识体系结构

应用程序:是一段可以执行的代码,由操作系统管理。

编译原理,链接器,装载器:是对操作系统依赖的一个工具,将用户的代码变成可执行的机器码,编译器仅仅检查和翻译用户的语言逻辑,但并不装配成符合操作系统要求的可执行文件格式,如windows要求的EXE文件为PE格式(EXE文件并不仅仅是一个可执行的代码段,而且包含了很多其他的内容,如数据段)。

操作系统接口API:是一个可以被用户程序调用的系统功能接口,可以说,我们编写程序,除了计算和流程控制这些只需要用到CPU指令和CPU寄存器的代码外,其余要访问其他(硬件)资源(包括内存,外设)的代码,均是通过调用OS的API来操作除CPU外的资源的,如向屏幕写一个字母,对于程序来说简单得很,print(“A”); 但是其编译后执行的过程是复杂的,编译后的程序会调用操作系统的API,将当前应用程序的状态(上下文,如光标的位置)以及字母传递给显示器的驱动程序去显示。

操作系统管理与调度:操作系统要实现一般通用的资源管理,也要实现资源使用的协调,包含CPU,内存,磁盘,外设。

首先要确定为什么需要操作系统,操作系统设计的目标是什么?

1.我们总是不能等做完一件事情才去做另外一件,因为有些事情做的过程需要等待,有时候也需要暂停一下当前的任务,先去处理更急的事情,等我回来

时又需要以前的任务保持当时的状态,所以需要计算机也要具备这样的能

力,那怎么实现呢?

2.CPU和内存是计算机的最需要的资源,就如我们的人脑一样,一般很难在同一时间做两件事情。需要处理好一件事情再处理另一件,如果处理得越快就

越好,但是不能前一件事情要等待,你就休息了,后面一件也做不了,计算

机的办法就是你不用CPU了,那好你等待下,我先处理下一个事情。

3.我们写程序,不可能对每个应用,我们重新去写那些驱动程序,也不可能按照自己的想法去处理这些通常的资源管理。否则很多人各自写的应用软件就

没法在一个电脑上运行。

操作系统目标:

1.实现代码重用,对于硬件的访问,对于CPU和内存的充分利用,使不同的应用不需要重新去写这些代码。

2.实现各个任务(不同应用程序)的协调使用,使用户可以实现暂停、重新启用某个任务。

3.实现数据的安全管理,实现良好的人机界面的管理。

4.实现一个开放的体系结构,提供系统调用使用户可以快速编写自己的应用,并提供编译器、链接器、装载器来让用户编写的程序变成可以与操作系统接口的

可执行软件。

操作系统的功能分层:

CPU管理是操作系统的核心:操作系统与用户程序其实可以看成是一个程序,与以前的单任务系统和单片机程序没有本质的区别。

我们来看整个PC机运行过程:

1.系统上电。

2.主板上CPU的CS值设置为0Fx000,IP值设置为0xFFF0,这样CS:IP就指向0xFFFF0位置,这个是程序的开始地址,而硬件上在总线上挂接在0xFFFF0地址

的是主板的BIOS芯片,BIOS开始运行,BIOS是Basic Input Output System简写,

意思即基本的输入输出系统,如果学过单片机就很好理解,其实就是一个程序,由主

板设计的公司的程序员编写的,通过一定的方法(如编程器)写入到芯片内,这段程序会一上电就开始运行。

3.BIOS会检查所有的主板资源,并初始化主板的硬件资源,如总线控制器、显示卡、内存等,并将主板的固有资源和接插件的信息放入固定的内存区域,以便操作系统可以从中获取得到当前的主板上有些什么设备资源。

4.BIOS会在内存地址的最低位0x000000构建起中断向量表,共1K内存(一个向量CS:IP各两个字节,共256个向量),接着是1/4K(256byte)的内存放BIOS数据,接下来在0x0E2CE(56K处)加载了8K左右的与中断向量表相应的若干中断服务程序。

5.当BIOS程序检测到主板上的设备符合启动系统的条件,就读取硬磁盘的引导扇区(第一扇区,这里也是一个程序,从哪个磁盘加载由CMOS设置确定),BIOS 系统将这段程序bootloader读入内存,并将控制权交给引导程序。

6.BIOS具有驱动硬盘等硬件的驱动程序,并且,具有基本的硬件驱动服务程序。这些都由主板硬件厂商提供。Bootloader会调用BIOS的驱动程序和已有的中断服务来从硬盘读取操作系统的核心到内存,并将CPU控制交给操作系统。(操作系统就如一段数据被映射到内存,然后程序通过修改CS:IP跳转到操作系统的入口。)7.操作系统会通过IGDT重新构建中断向量表。每个硬件产生的中断,其编号在硬件设计之初就已经设计好,外部硬件中断/CPU内部异常中断/程序调用中断,其中断号和程序是预先设置好的,当有外部中断时,中断寄存器IPR会暂时存储,并与中断屏蔽寄存器IMR进行AND位运算,然后就可以确定是否处理当前中断,这个是硬件电路实现的,运算后的结果经过中断处理(中断译码)进入CPU的中断寄存器IDTR,CPU执行完当前指令,会自动处理(检查)中断,并将CS:IP指向中断地址,这个地址是什么呢?在实模式下(16位模式),中断译码根据中断号N x 4(每个中断4个字节)直接设置IP,也就是中断的程序地址没法更改的,然后在中断向量的位置就是一个跳转指令,跳转到服务程序处。在保护模式下呢,中断向量的原理与组织与实模式基本一样,也是256个中断处理程序,但是其中断服务程序不在固定的位置,中断向量表也不在固定的位置,CPU的IDTR寄存器由操作系统在系统初始化之初就装入了中断向量表(中断门表)在内存中的寻址位置信息,保护模式下,硬件将IDTR和中断号N译码找到中断表的该中断描述项,而描述项说这个服务程序在GDT或LDT表中的第X项描述的段中,以及偏移多少可以找到程序,然后找到这个段的基址+32位的地址偏移量。

8.操作系统从实模式转保护模式时,最重要的一个是构建内存映射表和各种描述符

表。CPU访问内存时,是通过MMU进行了译码的,MMU的作用就是把CPU指令中的虚拟地址(是程序员编写的地址,一般高级语言编写的程序不直接写地址,但是程序装载到内存后,所有访问地址的指令都发生了地址修改,这是由装载器设置的。)变成实际的物理地址。

9.操作系统为什么需要MMU,计算机从主板启动后,是在ROM中运行的,速度相对于RAM来说是非常慢,我们就想到把程序复制到RAM中运行,但是计算机体系的执行是有固定的地址的,如CPU上电首先从0xFFFF0地址加载第一条指令,发生错误则会自动将IP指向0x0000开始的中断向量表,如果我们将程序COPY 到RAM运行,但是硬件一中断,还是会跑到硬件地址的0x0000处的向量表去运行,还是在ROM中,一样缓慢,为了解决这个问题,我们想到了地址转换,当将程序COPY到RAM中后,构建MMU的页表,然后启动MMU的地址转换功能,然后程序开始从我们设定的地址开始运行(如0xFFFA0),而CPU也为了与操作系统配合,也定义了保护模式,其运行规则也相应发生了变化,其IGTR中的值由实模式时的0x000变成了由操作系统定义的中断门表的地址。保护模式时的中断程序的寻址比实模式复杂,因其中断处理器硬件也复杂。而对于BIOS的ROM访问地址,也被映射到了新的虚拟地址空间,不再是0xFFFF0,所以对于ROM中的中断程序的访问,是通过IGTR+中断描述项定位到该内存地址。所有的外设的内存映射地址均被操作系统重新映射和管理。

(系统上电时,处理器的程序指针从0x0(或者是由0Xffff_0000处高端启动)处启动,顺序执行程序,在程序指针(PC)启动地址,属于非易失性存储器空间范围,如ROM、FLASH等。然而与上百兆的嵌入式处理器相比,FLASH、ROM 等存储器响应速度慢,已成为提高系统性能的一个瓶颈。而SDRAM具有很高的响应速度,为何不使用SDRAM来执行程序呢?为了提高系统整体速度,可以这样设想,利用FLASH、ROM对系统进行配置,把真正的应用程序下载到SDRAM 中运行,这样就可以提高系统的性能。然而这种想法又遇到了另外一个问题,当ARM处理器响应异常事件时,程序指针将要跳转到一个确定的位置,假设发生了IRQ中断,PC将指向0x18(如果为高端启动,则相应指向0vxffff_0018处),而此时0x18处仍为非易失性存储器所占据的位置,则程序的执行还是有一部分要在FLASH或者ROM中来执行的。那么我们可不可以使程序完全都SDRAM中运行那?答案是肯定的,这就引入了MMU,利用MMU,可把SDRAM的地址完全映射到0x0起始的一片连续地址空间,而把原来占据这片空间的FLASH或者ROM 映射到其它不相冲突的存储空间位置。例如,FLASH的地址从0x0000_0000-0x00ff_ffff,而SDRAM的地址范围是0x3000_0000-0x31ff_ffff,则可把SDRAM 地址映射为0x0000_0000-0x1fff_ffff而FLASH的地址可以映射到0x9000_0000-0x90ff_ffff(此处地址空间为空闲,未被占用)。映射完成后,如果处理器发生异常,假设依然为IRQ中断,PC指针指向0x18处的地址,而这个时候PC实际上是从位于物理地址的0x3000_0018处读取指令。通过MMU的映射,则可实现程序完全运行在SDRAM之中)

10.内存映射表:是为MMU构建的一块内存区域,其内容为一个表,或者叫一个数组,每个元素标记了[虚拟地址:物理地址],页表一般分两极,第一级为1M一个项,第二级则是1M内的索引。那会有多少呢,4G=4K项,然后每个1M=256项,

所以页表大小为1M,如果每个项为32bit,那么至少需要256K个指令周期才能把内存的页表装入MMU,也就是0.4ms, windows的CPU分时片为20ms。那么进程

切换的时间不少于1ms。

11.CPU中有是否启用MMU的寄存器设置,如果不启用,则CPU发出读写地址线信号,同时MMU不会做出反应,使能信号直接被MMU输出,RAM检测到指令,直接将数据放到总线上,并通知CPU数据准备好。如果启用MMU,CPU发出读写指令,MMU同时从总线获取地址数据经过硬件运算,仅仅一个硬件周期,然后修改总线的地址,并通知内存或北桥芯片地址准备好。

12.对于操作系统来说,只要构建每个进程的内存映射表,并在进程切换时将内存映射表复制到MMU的缓冲中。

13.而对于应用程序来说,是不能操作MMU的,所以,当企图访问没有映射的虚拟内存时,MMU会向CPU会产生缺页中断,然后在中断服务程序中,操作系统会根据是否是被换出内存还是没有初始化,来决定是从硬盘装载内存,或抛出异常错误。

14.操作系统的内存管理,是分段式管理,并在内存中构建了一个段描述符表,这个表是用来告诉大家(CPU,所有程序)每个段内放了什么东西,是可执行代码,或是数据,或者是一个只读存储器,或者这个部分是不能访问的。为什么要这样,因为系统的4G内存空间,其实是不连续的,所有的硬件都是挂接在总线的,CPU 只有通过32位总线来访问所有的非CPU的外设,包括MMU,RAM,北桥,硬件上CPU就仅与上面的器件通过32位总线连接,对于键盘、鼠标、显示器、PCI 卡、USB、电池芯片、声卡、网卡等等的访问,都是通过写地址总线,然后读数据总线(其实就是地址线,冯。诺伊曼结构的总线复用),来获取或写入一个数据。

而硬件的挂接地址是不连续的,我们访问内存地址时,就要清楚每个实际地址的用途,为了安全,在不清楚的情况下,即使发出错误指令,系统也会自动根据段的属性来检查是否处于保护中的地址,以免系统马上崩溃。不是说过Win32环境下不用“段”了吗?是的,这些“段”实际上并不是DOS汇编中那种意义的段,而是内存的“分段”。上一个段的结束就是下一个段的开始,所有的“分段”合起来,包括系统使用的地址空间,就组成了整个可以寻址的4 GB空间。由于Win32环境的内存管理使用了80386处理器的分页机制,每个页(4 KB大小)可以自由指定属性,所以上一个4 KB可能是代码,属性是可执行但不可写,下一个4 KB 就有可能是既可读也可写但不可执行的数据,再下面呢?有可能是可读不可写也不可执行的数据。Win32汇编源程序中“分段”的概念实际上是把不同类型的数据或代码归类,再放到不同属性的内存页(也就是不同的“分段”)中,这中间不涉及使用不同的段选择器。虽然使用和DOS汇编同样的.code和.data语句来定义,意思可是完全不同了!为了简单起见,在本书中还是简称“段”,读者应该注意到其中不同的含义。在程序中如果不小心用了对.const段中的数据做写操作的指令,会引起保护错误。在程序中不必定义堆栈段,系统会自动分配堆栈空间。

惟一值得一提的是,堆栈段的内存属性是可读写并且是可执行的,这样靠动态修改代码的反跟踪模块可以拷贝到堆栈中去边修改边执行。一些病毒或者黑客工具用到的缓冲区溢出技术也用到了这个特征,有兴趣了解的读者可以查阅相关的资料。

15.4K, 是windows管理内存的最小单位,每个4K的虚拟地址对应整块的4K实际地址,而每个实际的4K地址为一个段,每个段又有自己的存储属性。当程序访问某个虚拟地址时,MMU先获得虚拟地址与实地址的对应的页表描述项,描述项说地址我不知道,但是我知道他在操作系统的段表中,要么在GDT要么在LDT中的第N项,然后在GDT中的N项说这个段是不能被访问的,MMU就报告出错了,

如果可以访问,那么就根据这个段的起始地址+ (虚拟地址/ 4K的余数就是段

内偏移地址。)

16.Windows的内存分配机制,当应用程序调用操作系统的内核程序申请一个内存区域,内核程序会根据当前的应用程序的内存使用链表来来决定是否需要申请新

的页(段),如果在当前已经申请的4K内存页还有符合申请的大小块就直接重建

链表,分配一个地址给当前进程,可见当前的进程的内存的分配也是操作系统管

理的。

17.DMA控制器,用于管理两个外设之间的数据流传输,如控制从磁盘读取数据进入内存,DMA控制器是一个连续地址信号发生器,同时也有读写的方向时序控

制,数据不经过CPU,由DMA控制直接在总线上传输。

设备驱动程序:

操作系统的驱动程序结构,首先明白计算机硬件与CPU及操作系统的关系,操作系统的代码仅仅在CPU中运行,所以只要CPU支持该操作系统的指令代码,就可以启动操作系统,而至于访问硬件的过程,就是读取内存地址的过程(MOV eax, &0xFFF330),对于i386其IO地址是独立的地址空间0x0000-0xFFFF共64K所以CPU的地址空间对于i386有两个,访问的指令也有两种,而对于ARM这些来说IO地址是被编址到32位内存地址空间的,所有外设也被挂接到内存总线上的。这些硬件的物理地址在主板制造好时就已经定了,无法更改,而BIOS的功能之一也就是收集这些设备与IO的地址对应信息,并交给操作系统。然后操作系统根据BIOS提供的设备信息安装相应的设备驱动程序给操作系统内核使用。如果BIOS不提供这些设备的IO信息,那么操作系统怎么办呢,那操作系统不可能搜索整个IO 地址空间来确定有哪些设备,所以也就没法知道有哪些外设IO。外设的IO分配是主板设计者决定的,每个设备均有连续的三部分寄存器IO地址,1。控制寄存器,2。数据寄存器,3。状态寄存器。通过对寄存器的读写,也就是执行指令IN/OUT 0xFFFF,来读写寄存器实现对于外设的操作,可以看到,这个与单片机对于单个引脚的控制方法不同。PC机的目标是数据交换和处理,而单片机的目标主要是控制每个引脚的电平实现硬件的控制。

操作系统会自带一些驱动程序,那么这些自带的驱动程序怎么与实际的硬件关联起来呢。

下面我们来看USB鼠标的驱动,在windows的设备管理器中我们可以发现,鼠标项,其中可以找到HID鼠标,这个是一个符合USB设备类HID类的串行设备,我们发现这个设备没有硬件资源,也就是说没有对应的IO地址和中断号。所以这个不是一个真实的独立的设备,它是一个windows的高层设备,也可以叫这个设备是一个虚拟的接口设备,我们可以采用windows的一般鼠标驱动程序来操作这个设备。而实际上对于它的操作,会被该设备关联的驱动程序所接管,而其关联的驱动程序是什么能,是windows自带的USB HID类驱动程序,对于USB的HID类设备,其操作协议有固定的规范,所以可以直接驱动。那么USB HID驱动程序又怎么驱动实际的硬件呢,我们可以在windows的设备管理器中找到该鼠标对应的USB控制器,而该控制器有IO地址1840-185F共32个字节空间以及中断号18,那么这个地址和中断号怎么来的呢,这个就是BIOS告诉操作系统的,地址和中断号是主板设计时就已经定了的。所以在不同的PC上装的windows,其IO地址和中断也不同。

bios启动,可以访问VGA,也可以设定从磁盘或USB设备启动,说明BIOS已经可以驱动所有设备,其实上BIOS已经构建起中断向量表,对于挂接到中断总线的所有设备产生的硬件中断已经具有响应能力,BIOS启动后,从CDROM或硬盘或USB设备装载引导程序,最开始没有安装操作系统时,引导程序是一个引导安装系统的程序,安装程序启动运行会根据BIOS的设置来配置操作系统,在windows中明显的就是改变注册表,注册表是系统能用的所有硬软件资源的描述。安装完成后,系统就进入正式的系统。在没有安装更多主板驱动程序之前,所有的底层硬件驱动就是通过中断服务程序提供的,如USB的控制驱动程序,也可以说是总线驱动程序,响应硬件中断和软件中断,提供硬件访问服务,怎么在中断服务(USB总线驱动)和操作系统的通用驱动程序接口之间建立对应的关系呢,对于即插即用硬件来说,这个映射过程是动态的,当没有鼠标接入USB端口时,内存中就存在对于中断18响应的USB控制器驱动程序,但是什么也不做。当有鼠标插入USB端口,首先鼠标的USB芯片得电运行,同时USB的数据线会拉底主机的USB控制器接口的数据线接口的电平,硬件就会知道有设备接入,直接发送USB控制数据包,读取设备的配置信息,知道了设备的描述信息后进一步配置设备信息,同时通过挂接在中断总线上的引脚产生中断信号18,中断服务程序进一步与鼠标芯片交流,确定为HID设备后,中断服务程序会搜索其成员对象中能处理HID类别的驱动程序来与这个设备通信。而这个HID驱动程序在哪呢,什么时候又与中断服务关联了呢,这个就是BIOS与操作系统的交互过程,操作系统启动后,会将自己的三类USB驱动程序挂接到中断服务中,怎么挂接?操作系统直接调用BIOS的函数表中的函数将驱动程序的指针加到服务程序的驱动程序列表,然后所有的来自鼠标的中断均被转发到HID驱动来处理,而HID做了什么,HID会检查设备的类型和设备供应商及ID,并从本驱动的附属驱动中找到最合适的驱动并交给它处理,如果没有找到驱动,则调用操作系统的硬件驱动程序的安装流程,驱动程序安装好后,驱动程序初始化会向HID驱动登记自己,并在操作系统中注册一个鼠标类别的设备,并将标准的鼠标驱动放到本驱动中,当鼠

标移动,首先鼠标的移动数据被保存到鼠标的USB芯片的寄存器中,并产生USB传输数据申请,USB控制器读取寄存器的数据到主机的USB寄存器中,如0x1850处,然后申请中断处理,中断程序获取到寄存器数据,并传递给USB鼠标器驱动程序,USB鼠标驱动程序调用操作系统的标准鼠标处理程序(标准驱动程序)来处理命令,一般就是鼠标驱动会通知windows的窗口管理进程重画整个界面(鼠标位置数据已变更)。

当我们要访问USB端口时,我们不能直接读写USB端口,因为USB端口是由控制器管理的,当没有挂接设备的时候,windows中也没有对应的设备项目,因此也就没法通过readFile/writeFile来操作没有对象的设备了。

当有一个可以读写的USB设备别挂接时,如USB转串口芯片,系统开始找不到驱动就安装,安装好后,驱动程序会向系统注册一个COM端口,而该设备的驱动程序指向芯片特有的驱动程序,芯片驱动程序会调用USB总线驱动将数据传输到芯片端,而这个数据格式是驱动程序根据芯片定制的,当收到数据时,芯片驱动程序会将接收到得数据传递给通用COM驱动给其处理。

对于U盘操作,那些通用的磁盘驱动程序,Scsi的函数都只是在准备一些缓冲区、数据结构等,并没有对硬件进行操作,真正要操作硬件设备的还是由驱动程序来完成的,可见,设备驱动程序是有着很强层次结构的,下层是专门针对物理设备的,上层是针对操作系统的抽象设备的,下层是U盘等物理实体,上层是文件夹,二者通过一定的通信或调用机制完成了设备在操作系统下的正常工作。U盘插入,系统调用安装设备驱动程序,U盘驱动初始化设备,当第一次加入内存,U盘驱动程序修改了总线驱动的设备驱动程序列表,将自己挂接在总线上进行监控,同时修改了系统的设备清单,应用程序读写这个磁盘时不是通常的ReadFile和writeFile,而是通过DeviceIOControl来传递命令控制设备的,首先调用的U盘驱动程序,然后由设备驱动程序调用通用的DISK处理程序来处理,处理完成后,最后调用设备驱动程序的实际硬件操作。

总线驱动:

CPU与主板的配合

外设接口原理

WebDriver 之测试失败自动截图

WebDriver 之测试失败自动截图 webDriver 测试的时候最头疼的就是调试。但也远不及运行的时候出错,再回头调试来的痛苦。总所周知, web 自动化的代码都非常脆弱,一份代码一会运行失败,一会运行成功也是很正常的事情。总的来说造成案例运行失败的原因大抵有两点:环境问题:比如网络不稳定啊 代码变动:比如某个元素不在 遇到 bug :这就是真的发现 bug 了 无论哪一种,遇到了都需要花一番时间去debug。那如果这个时候有一张运行时候出错的截图,那就一目了然了。(即便不一目了然,也有很多帮助) 在运行出错的时候,捕获错误并截图有两种思路: 自定义一个WeDdriver 的监听器,在出异常的时候截图。 利用Juint 的TestRule,自定义一个Rule 在运行失败的时候截图。 自定义监听器 截图的原理 截图需要用到RemoteWebDriver。在 Selenium 官方我们可以找到: One nice feature of the remote webdriver is that exceptions often have an attached screen shot, encoded

as a Base64 PNG. In order to get this screenshot, you need to write code similar to: public String extractScreenShot(WebDriverException e) { Throwable cause = e.getCause(); if (cause instanceof ScreenshotException) { return ((ScreenshotException) cause).getBase64EncodedScreenshot(); } return null; } 意思就是说,每个异常都是ScreenshotException 的对象,转码一下就可以用了。这是截图的本质。 import java.io.File; import java.io.FileOutputStream; import java.io.IOException; import java.text.SimpleDateFormat; import java.util.Date; import org.openqa.selenium.WebDriver;

微机原理实验 源程序

《微机原理及接口技术》 实验指导书 杨霞周林英编 长安大学电子与控制工程学院 2009年9月

前言 本实验指导是为适应各大、中专院校开设微机原理及应用方面的课程需做大量软硬件实验的需要而编写的,供学生编程用。完成本实验指导中的实验,可使学生基本掌握8086/8088的结构原理、接口技术、程序设计技巧。手册中详细叙述了各实验的目的、内容,列出了接线图、程序框图和实验步骤。 主要学习内容为80X86语言实验环境配置、汇编源语言格式、输出字符、循环结构、子程序调用,以及加减乘除等指令操作、通用接口芯片的接口编程与使用。所有实验都是相互独立的,次序上也没有固定的先后关系,在使用本书进行教学时,教师可根据教学要求,选择相应实验。学习结束后,要求学生能够独立编写出综合加减乘除等指令,以及循环结构、子程序调用等程序控制程序、看懂一般接口芯片电路图。

目录 实验一清零程序 (4) 实验二拆字程序 (6) 实验三数据区移动 (8) 实验四多分支程序设计 (10) 实验五多字节减法运算 (13) 实验六显示程序 (16) 实验七 8251串口实验 (20) 实验八步进电机控制 (26) 附录一汇编语言的存储模型 (36) 附录二 8279键值显示程序 (37)

实验一清零程序 一、实验目的 掌握8088汇编语言程序设计和调试方法。 二、实验设备 STAR系列实验仪一套、PC机一台。 三、实验内容 把RAM区内4000H-40FFH单元的内容清零。 四、程序框图 五、源程序清单 .MODEL TINY .STACK 100 .DATA .CODE ORG 0100H START: MOV BX,4000H MOV AX,0000H MOV CX,80H L1: MOV [BX],AX INC BX INC BX LOOP L1 JMP $ END START 六、实验步骤

微机原理程序 (2)

实验二:循环程序设计 2. DA TA SEGMENT x db -78,127,-128,-125,88 y db 32,-43,76,95,1 S db 5 dup(?) data ends Code segment Assume cs:code,ds:data Start:mov ax,data Mov ds,ax Mov cx,5 Mov bx,0 L1:mov al,x[bx] Add al,y[bx] Inc bx Loop L1 MOV AH,4CH INT 21H CODE ENDS END START 3. DA TA SEGMENT Y DB 68H,24H,90H,57H,13H HX DB 67H,34H,12H,90H,57H S DB 5 DUP(?) DA TA ENDS CODE SEGMENT ASSUME CS:CODE,DS:DA TA START:MOV AX,DATA MOV DS,AX MOV CX,5 MOV SI,OFFSET X MOV DI,OFFSET Y LP:MOV AL,[SI] MOV AH,[DI] ADC AL,AH DAA MOV S[SI],AL INC SI INC DI LOOP LP MOV AH,4CH INT 21H

CODE ENDS END START 4、 DA TA SEGMENT LIST DB 0,1,2,3,4,5,6,7,8,9 COUNT EQU $-LIST DA TA ENDS CODE SEGMENT ASSUME CS:CODE,DS:DA TA START:MOV AX,DATA MOV DS,AX MOV CX,COUNT-1 LOOP1:MOV DX,CX MOV BX,0 LOOP2:MOV AX,LIST[BX] CMP AX,LIST[BX+1] MOV LIST[BX],AX LOOP3:INC BX LOOP LOOP2 MOV CX,DX LOOP LOOP1 MOV AX,4CH INT 21H CODE ENDS END START 实验三:子程序调用程序设计 DA TA SEGMENT NUM DB 85,77,126,-1,-43,37,-128,11,-19,13 DA TA ENDS ADDITION SEGMENT NUM1 DB 10 DUP(?) ADDITION ENDS CODE SEGMENT ASSUME CS:CODE,DS:DA TA,ES:ADDITION START:AX,DATA MOV DS,AX MOV AX,ADDITION MOV ES,AX CALL ORDER CALL COPY MOV AH,4CH INT 21H ORDER PROC MOV CX,9

pythonwebdriver自动化测试实战

. python webdriver 项目实战 文档Word . 第5章测试模型与测试脚本优化 第一节、测试模型介绍 线性测试通过录制或编写脚本,一个脚本完成用户一套完整的操作,通过对脚本的回放来进行自动化测试。这是早期进行自动化测试的一种形式;我们在上一章中练习使用webdriver API 所编写的脚本也是这种形式。 脚本一 fro selenium impor webdriver impor time driver = webdriver.Firefox() driver.get睜睷?硸) driver.find_element_by_id瑜啢敳乲浡).send_keys甥敳湲浡) driver.find_element_by_id瑜偢獡睳牯).send_keys???) driver.find_element_by_id扜湴潌楧).click() 执行具体用例操 ...... driver.quit ()脚本二 from selenium import webdriver import time driver = webdriver.Firefox() driver.get(睜睷?硸?) driver.find_element_by_id(瑜啢敳乲浡履).send_keys(甥敳湲浡履)

driver.find_element_by_id(瑜偢獡睳牯層).send_keys(???尶) driver.find_element_by_id(扜湴潌楧屮).click() #执行具体用例操作 文档Word . ...... driver.quit ()通过上面的两个脚本,我们很明显的发现它的问题: 一个用例对应一个脚本,假如界面发生变化,用户名的属性发生改变,不得不需要对每一个脚本进行修改,测试用例形成一种规模,我们可能将大量的工作用于脚本的维护,从而失去自动化的意义。 这种模式下数据和脚本是混在一起的,如果数据发生变也也需要对脚本进行修改。 这种模式下脚本的可重复使用率很低。 模块化与库 我们会清晰的发现在上面的脚本中,其实有不少内容是重复的;于是就有了下面的改进。login.py 登录模de login(): driver.find_element_by_id瑜啢敳乲浡).send_keys甥敳湲浡) driver.find_element_by_id瑜偢獡睳牯).send_keys??㈱) driver.find_element_by_id扜湴潌楧).click() 测试用例:#coding=utf-fro selenium impor webdriver 文档Word . 注意,上面代码并非完整代码,不能运行。

微机原理及应用实验(题目)

微机原理及应用实验 实验一开发环境的使用 一、实验目的 掌握伟福开发环境的使用方法,包括源程序的输入、汇编、修改;工作寄存器内容的查看、修改;内部、外部RAM内容的查看、修改;PSW中个状态位的查看;机器码的查看;程序的各种运行方式,如单步执行、连续执行,断点的设置。二、实验内容 在伟福开发环境中编辑、汇编、执行一段汇编语言程序,把单片机片内的 30H~7FH 单元清零。 三、实验设备 PC机一台。 四、实验步骤 用连续或者单步的方式运行程序,检查30H-7FH 执行前后的内容变化。五、实验思考 1.如果需把30H-7FH 的内容改为55H,如何修改程序? 2.如何把128B的用户RAM全部清零? 六、程序清单 文件名称:CLEAR.ASM ORG 0000H CLEAR: MOV R0,#30H ;30H 送R0寄存器 MOV R6,#50H ;50H 送R6寄存器(用作计数器) CLR1: MOV A,#00H ;00 送累加器A MOV @R0,A ;00 送到30H-7FH 单元 INC R0 ;R0 加1 DJNZ R6,CLR1 ;不到50H个字节,继续 WAIT: LJMP WAIT END 实验二数据传送 一、实验目的 掌握MCS-51指令系统中的数据传送类指令的应用,通过实验,切实掌握数据传送类指令的各种不同的寻址方式的应用。 二、实验内容 1.编制一段程序,要求程序中包含7中不同寻址方式。 2.编制一段程序,将片内RAM30H~32H中的数据传送到片内RAM38H~3AH中。 3.编制一段程序,将片内RAM30H~32H中的数据传送到片外RAM1000H~1002H 中。 4.编制一段程序,将片内RAM40H~42H中的数据与片外RAM2000H~2002H中的数据互换。 三、实验设备 PC机一台。

微机原理程序

一,在数据段从TABLE开始定义10无符号的数据,每个数据为一个字节,计算这10个数的和,结果放到SUM字单元之中 DA TA SEGMENT TABLE DB 12H, 23H, 34H, 45H, 56H DB 67H, 78H, 89H, 9AH, 0FDH SUM DW DA TA ENDS STACK SEGMENT D8 5 DUP(?) STACK ENDS CODE SEGMENT ASSUME CS: CODE, DS: DATA, SS: STACK START: MOV AX, DATA MOV DS, AX MOV ES, AX MOV AX,STACK MOV SS, AX LEA SI, TABLE MOV CX, 10 XOR AX, AX NEXT: ADD AL , 0 INC SI LOOP NEXT MOV SUM, AX MOV AH, 4CH INT 21H CODE ENDS ENDS START

二,在数据段自TABLE开始的连续10个单元中有放在0-9的平方值,查表求任意数X (0<=X<=9)的平方值,并将结果放到RESULT中 三,在数据段定义2个数据,每个数据占有若干字节,按照低地址存储低数据位的原则存储,这两个数据长度一样,计算这2个数据的和,并将结果放到RESULT中。 四、用8255PA作开关量输入口,PB作输出口。 CODE SEGMENT ASSUME CS:CODE ,DS:CODE ,ES:CODE ORG 32E0H PA EQU 0FFD8H PB EQU 0FFD9H PC EQU 0FFDAH PCTL EQU 0FFDBH HI:MOV DX,PCTL MOV AL,90H OUT DX,AL PI:MOV DX,PA IN AL,DX INC DX OUT DX,AL JMP PI CODE ENDS END HI

MOS管及简单CMOS逻辑门电路原理图

MOS管及简单CMOS逻辑门电路原理图 现代单片机主要是采用CMOS工艺制成的。 1、MOS管 MOS管又分为两种类型:N型和P型。如下图所示: 以N型管为例,2端为控制端,称为“栅极”;3端通常接地,称为“源极”;源极电压记作Vss,1端接正电压,称为“漏极”,漏极电压记作VDD。要使1端与3端导通,栅极2上要加高电平。 对P型管,栅极、源极、漏极分别为5端、4端、6端。要使4 端与6端导通,栅极5要加低电平。 在CMOS工艺制成的逻辑器件或单片机中,N型管与P型管往往是成对出现的。同时出现的这两个CMOS管,任何时候,只要一只导通,另一只则不导通(即“截止”或“关断”),所以称为“互补型CMOS管”。 2、CMOS逻辑电平 高速CMOS电路的电源电压VDD通常为+5V;Vss接地,是0V。 高电平视为逻辑“1”,电平值的范围为:VDD的65%~VDD(或者~VDD)

低电平视作逻辑“0”,要求不超过VDD的35%或0~。 +~+应看作不确定电平。在硬件设计中要避免出现不确定电平。 近年来,随着亚微米技术的发展,单片机的电源呈下降趋势。低电源电压有助于降低功耗。VDD为的CMOS器件已大量使用。在便携式应用中,VDD为,甚至的单片机也已经出现。将来电源电压还会继续下降,降到,但低于VDD的35%的电平视为逻辑“0”,高于VDD的65%的电平视为逻辑“1”的规律仍然是适用的。 3、非门 非门(反向器)是最简单的门电路,由一对CMOS管组成。其工作原理如下:A端为高电平时,P型管截止,N型管导通,输出端C的电平与Vss保持一致,输出低电平;A端为低电平时,P型管导通,N型管截止,输出端C的电平与V一致,输出高电平。 4、与非门

Webdriver定位不到元素的解决办法

Webdriver定位不到元素的解决办法 Webdriver定位不到元素的解决办法 不知道怎么回事,先前能跑动的case,现在元素始终找不到。但是我xpath是能定位得到的,debug了一下,结果发现在WebElementelement = locator.findElement();就卡 住了。弄了好久也没有成功。网上找例子:Selenium2(WebDriver)_如何判断WebElement元素对象是否存在 1.selenium中如果去寻找元素,而元素不存在的话,通常会抛出NoSuchElementException 导致测试失败,但有时候,我们需要去确保页面元素不存在,才是我们正确的验收条件下面的方法可以用来判定页面元素是否存在 1 public boolean doesWebElementExist(WebDriver driver, By selector)2{3 4 try 5 { 6 driver.findElement(selector);7 returntrue;8 }9 catch(NoSuchElementException e)10 {11 return false; 12 }13 } 2.一般有这样的应用场合,例如我们要验证在一个网站是否登录成功,那么可以通过判

断登录之后是否显示相应元素:WebElementlinkUsername =driver.findElement(By.xpath("//a[contains(text(),"+username+" )]"));return linkUsername.isDisplayed();这一方法的前提是:该元素之前已经存在,仅仅需要判断是否被显示。现在存在另一种场合,页面元素并不存在,即通过driver.findElement只能在超时之后得到NoSuchElementException的异常。因此只好通过如下方法解决:1 boolean ElementExist (ByLocator )2{3 try4 {5 driver.findElement( Locator );6 returntrue;7}8 catch(org.openqa.selenium.NoSuchElementException ex)9{10 returnfalse;11 }12 }

微机原理程序题

1. 将下面C语言程序的代码片段转换为功能等价的汇编语言代码片段,其中sign与sinteger 均为双字变量。 if ( sinteger = = 0) sign = = 0; else If ( siteger > 0) sign = 1; else sign = -1; mov eax,sinteger mov edx,sign cmp eax,0 jnz L1 mov ebx,0 L1:cmp ebx,0 jl L2 mov ebx,1 L2:mov ebx,-1 2. 将下面C语言程序的代码片段转换为功能等价的汇编语言代码片段,其中ch1与caps均为字节变量。 if (ch1> =’a’ && ch1< =’z’) caps= =0; if (ch1> =’A’ && ch1< =’Z’) caps= =1; mov ax,ch1 mov bx,caps cmp ax,a jb next cmp ax,z ja next mov bx,0 next:cmp ax,A jl done cmp ax,Z ja done done: 3. 将下面C语言程序的代码片段转换为功能等价的汇编语言代码片段,其中sum与i变量均为双字变量。 sum=0; for ( i=1;i< =100;i++) if ( i%2= =0) sum=sum+i; mov ecx,i mov ecx,1 .while(ecx<=100)

mov eax,ecx xor edx,edx mov ebx,2 div ebx cmp edx,0 jnz next add sum,ecx next:inc ecx .endw 1. 能被4整除但不能被100整除,或者年被400整除的年份是闰年。编程写一个完整的程序,求出2012年~2099年中的所有闰年年份,并把它们存放在数组Lyear中。 算法描述 ; esi=0;ecx=2012; ; while (ecx<2100) ; { if (year mod 4=0 and year mod 100 <>0) or (year mod 400=0) then ; {Lyear[esi]=ecx;esi++;} ; ecx++; ; } ; Lcounter=esi; include io32.inc .data Lyear dword 100 dup(?) Lcounter dword 0 .code mainproc xor esi,esi ;esi闰年个数计数器,兼做Lyear下标。 mov ecx,2012 ;ecx年份计数器。 .while (ecx<2100) mov eax,ecx xor edx,edx mov ebx,400 div ebx cmp edx,0 jz leap ;if year mod 400=0 then goto leap mov eax,ecx xor edx,edx mov ebx,4 div ebx cmp edx,0 jnz next ;if year mod 4<>0 then goto next mov eax,ecx xor edx,edx mov ebx,100 div ebx

selenium webdriver+python基本操作

selenium webdriver+python的基本操作 quit() 退出并关闭某程序,browser.quit() .close() 关闭窗口,Browser.close() time.sleep() 函数 设置某个位置停留一段时间,在哪里想停留就在哪里插入此函数,括号里为秒数,注意:使用此函数,要import time。

设置登录成功后停留了10秒,然后关闭页面 在适当的位置加入time.sleep()有助于减少网络原因造成的脚本执行失败.title 返回当前页面的标题 browser.title .forward() 前进,browser.foeward() .back() 后退,browser.back() .refresh() 刷新,browser.refresh()

.current_url 返回当前页面url,browser.current_url .window_handles 返回当前浏览器的所有窗口,browser.window_handles .current_window_handle 返回当前浏览器的窗口句柄,browser.current_window_handle .swatch_to_window(“window_name”) 选择窗口,browser.switch_to_window(“要切换到的窗口名”) 对话框操作 .switch_to_alert() 选择窗口对象 accept() 点击“确认” .dismiss() 点击“取消” text 获取文本值

Send_keys(‘keys’) 输入值 定位元素 Id定位 browser.find_element_by_id(‘id’) name定位 browser.find_element_by_name(‘name’) css定位 CSS(Cascading Style Sheets)是一种语言,它被用来描述HTML和XML文档的表现。CSS使用选择器来为页面元素绑定属性。这些选择器可以被selenium用作另外的定位策略。 CSS的比较灵活可以选择控件的任意属性 browser.find_element_by_css_selector(‘#foo’) css定位可以取name属性,如: 新闻 driver.find_element_by_css_selector("a[name=\"tj_news\"]").click() 可以取title属性,如: 网页 driver.find_element_by_css_selector("a[title=\"web\"]").click() 也可以是取..: driver.find_element_by_css_selector("a.RecycleBin").click()

微机原理实验报告软件实验1-4

微机原理实验报告 学院:算机科学与软件教育学院 1. 掌握存储器读写方法 2. 了解存储器的块操作方法 二、实验原理 存储器读写和块操作 三、实验设备仪器及材料 计算机,WA VE 6000软件 四、实验过程 S1.asm 代码流程图 data segment Block db 256 dup(55h) data ends code segment assume cs:code, ds:data start proc near mov ax, data mov ds, ax mov bx, offset Block ; 起始地址 mov cx, 256 ; 清256 字节Again: mov [bx], byte ptr 0 inc bx ; 地址+1 Loop Again ; 记数减一jmp $ ;死循环code ends end start

五、实验步骤 (1) 进入Wave6000,输入程序并检查,保存程序。 (2) “编译”程序。 (3) “全速执行”程序。 (4) “暂停”程序运行,在“数据窗口(MEMOREY)”查看0400H起始的单元内容,并记录。 (5) 在指令“jmp $”处设断点。“全速执行”程序。 (6) 在“数据窗口(MEMOREY)”查看0400H起始的单元内容,记录并分析实验结果。 六、实验结果及总结 运行前:运行后: 2、调试:如何将存储器块的内容置成某固定值(例全填充为0FFH)? 总结:通过本实验,我了解到单片机读写存储器的读写方法,同时也了解到单片机编程,调试方法。学会内存的移动方法,也加深对存储器读写的认识。

微机原理实验报告 学院:算机科学与软件教育学院 实验 课程 名 微机原理实验成绩实验 项目名称实验二、二进制到BCD码转换 指导老 师 1. 了解BCD值和ASCII值的区别。 2. 了解如何将BCD值转换成ASCII值。 3. 了解如何查表进行数值转换及快速计算。 二、实验原理 ASCII码表 三、实验设备仪器及材料 计算机,WA VE 6000软件 data segment Result db 3 dup(?) data ends code segment assume cs:code, ds:data start proc near mov ax, data mov ds, ax mov ax, 123 mov cl, 100 div cl mov Result, al ; 除以 100, 得百位数 mov al, ah mov ah, 0 mov cl, 10 div cl mov Result+1, al ; 余数除以 10, 得十位数 mov Result+2, ah ; 余数为个位 数 jmp $ code ends end start 代码流程图

微机原理练习六--读程序并回答问题

微机原理练习六读程序并回答问题 1. 已知,(DS)=2000H,(BX)=100H,(SI)=0002H,从物理地址20100H单元开始,依次存放数据12H、34H、56H、78H; 而从物理地址21200H单元开始,依次存放数据2AH、4CH、8BH、98H。试说明下列各条指令单独执行后AX寄存器的内容。 ① MOV AX,3600H (AX)= ② MOV AX,[1200H] (AX)= ③ MOV AX,BX (AX)= ④ MOV AX,[BX] (AX)= 2. 以下语句汇编后,变量CON1、CON2、CON3和CON4的内容分别是多少? N1=10 N2=5 N3=3 CON1 DB NOT N1 CON2 DB (N1 AND N2 OR N3)GE 0FH CON3 DW (N2 AND N1 XOR N3)LE 0FH CON4 DB (N1 AND N3 OR N2)LT 0FH 3. 读下列程序,并在空白处填入合适指令,使该程序段能完成将100H个字节数据从2000H处搬到1000H处的操作。 MOV SI,2000H MOV CX,100H CLD 4 指出下面指令序列的执行结果。 MOV DX,2000H MOV BX,1000H XCHG BX,DX 则:BX= DX= 5 设初值AX=6264H,CX=0001H,在执行下列程序段后,AX=?CX=? AND AX,AX JZ DONE SHL CX,1 ROR AX,CL DONE:OR AX,1234H 则:AX= CX=

6有数据定义如下,与之等同功能的指令是什么? DAT DW 100 DUP(?) : MOV CX,LENGTH DAT ADD AX,TYPE DAT 7. 指出下面指令序列的执行结果。 MOV AX,1234H PUSH AX POP BX 则:BX= AX= 8. 对于给定的数据定义,变量R1和R2的值分别是多少? ①A1 DB 1,2,3,‘ABC’ A2 DB 0 R1 EQU A2-A1 则R1= ②K1 DW ? K2 DB 6 DUP(?) R2 EQU $-K1 则R2= 9. 选用最少的指令,实现下述要求的功能。 ①AH的高4位清0,其余位不变。 ②AL的高4位取反,其余位不变。 ③AL的高4位移到低4位,高4位清0。 ④AL的低4位移到高4位,低4位清0。 10. 下面一段程序完成对某一缓冲区置全“1”操作。设缓冲区长度为20个字节,缓冲区首址DI=0200H,并设(ES) =3000H,试填空。 CLD MOV AX,3000H MOV DI,0200H MOV AL,0FFH REP STOSB 11. 下列伪指令在存储区中分别为各变量分配多少字节? VR1 DW 10 VR2 DW 6DUP(?),66,88 VR3 DD 10DUP(?) VR4 DB ‘HOW ARE YOU’ 12. 写出下列程序段执行后的结果,并说出完成的是什么功能? MOV CL,4 MOV AL,87H MOV DL,AL AND AL,0FH OR AL,30H SHR DL,CL OR DL,30H 则(AL)= (DL)= 实现的功能为13. 分析程序段,并填入适当的内容。 MOV AL,0FH

webdriver文档

A快速开始 1.安装selenium webdriver(eclipse+jdk+testng+selenium webdriver2.20+firefox 10) 1、安装firefox,使用firefox10。确保firefox安装在默认环境下(不是的话会报错)。 2、安装jdk,确保安装了jdk,我使用是java。但selenium webdriver也支持其它语言,如ruby、python、C#等。 3、安装eclipse。 4、安装selenium webdriver(https://www.doczj.com/doc/09928644.html,/download/下载selenium rc 2.21.0)。解压下载的selenium webdriver包,在eclipse中你建立的项目中导入所下载的包。(如下提示) 注:1.右键项目—选择build path选项—选择configure build path点击 2.选择右侧add external jars(如图)

3.找到所下载的selenium-server-standalone-2.21.0包,点击确定

4.点击ok,包就能导入项目

2.配置testng 1.介绍 TestNG是一个设计用来简化广泛的测试需求的测试框架,从单元测试(隔 离测试一个类)到集成测试(测试由有多个类多个包甚至多个外部框架组成的整 个系统,例如运用服务器)。 a. TestNG是一个设计用来简化广泛的测试需求的测试框架,从单元测试到 集成测试 这个是TestNG设计的出发点,不仅仅是单元测试,而且可以用于集成测试。设计目标的不同,对比junit的只适合用于单元测试,TestNG无疑走的更远。可以用于集成测试,这个特性是我选择TestNG的最重要的原因。 b. 测试的过程的三个典型步骤,注意和junit(4.0)相比,多了一个将测试 信息添加到testng.xml 文件或者build.xml 测试信息尤其是测试数据不再写死在测试代码中,好处就是修改测试数据 时不需要修改代码/编译了,从而有助于将测试人员引入单元测试/集成测试。 c. 基本概念,相比junit的TestCase/TestSuite,TestNG有 suite/test/test method 三个级别,即将test/test method 明确区分开了。 2.配置testng 1.Eclipse中点击Help->Install new software 2.点击Add 在Location输入https://www.doczj.com/doc/09928644.html,/eclipse

微机原理实验程序

实验一两个多位十进制数相减实验 一、实验要求:将两个多位十进制数相减,要求被减数,减数均以ASCII码形式按顺序 存放在以DATAI和DATA2为首的5个内存单元中(低位在前>,结果送回 DATAI处。 二、实验目的:1.学习数据传送和算术运算指令的用法。 2.熟悉在PC机上建立、汇编、链接、调试和运行汇编语言程序的过程。 三、实验步骤:连好实验箱后接通电源,打开上位机软件88TE进入软件调试界面: 点击“文件\打开”文件路径为C: \88TE\cai\asm\Ruanjian\Rjexp1.asm。具体操作如图所示: b5E2RGbCAP

点击编译连接生成可执行的exe文件。 通过单步运行调试程序,打开寄存器查看其变量变化情况。 四、实验程序框图: 五、实验程序:

文件路径为C:\88TE\cai\asm\Ruanjian\Rjexp1.asm DATA SEGMENT DATA1 DB 33H,39H,31H,37H,38H 。第一个数据<作为被减数)DATA2 DB 36H,35H,30H,38H,32H 。第二个数据<作为减数)MES1 DB '-','$' MES2 DB '=','$'p1EanqFDPw Array DATA ENDS STACK SEGMENT STA DB 20 DUP(?> TOP EQU LENGTH STA STACK ENDS CODE SEGMENT ASSUME CS:CODE,DS:DATA,SS:STACK,ES:DATA START: MOV AX,DATA MOV DS,AX MOV ES,AX MOV AX,STACK MOV SS,AX MOV AX,TOP MOV SP,AX MOV SI,OFFSET DATA1 MOV BX,05 CALL DISPL MOV AH,09H LEA DX,MES1 INT 21H MOV SI,OFFSET DATA2 MOV BX,05 CALL DISPL MOV AH,09H LEA DX,MES2 INT 21H MOV SI,OFFSET DATA1 MOV DI,OFFSET DATA2 CALL SUBA 。减法运算 MOV SI,OFFSET DATA1 MOV BX,05 。显示结果 CALL DISPL MOV DL,0DH MOV AH,02H INT 21H MOV DL,0AH MOV AH,02H INT 21H INT 21H MOV AX,4C00H INT 21H DISPL PROC NEAR 。显示子功能 DSI: MOV AH,02 MOV DL,[SI+BX-1] 。显示字符串中一字符 INT 21H

微机原理程序

;**********************; ;* 数/模转换实验1 *; ;* 产生锯齿波 *; ;**********************; io0832a equ 290h code segment assume cs:code start: mov cl,0 mov dx,io0832a lll: mov al,cl out dx,al add cl,10 push dx mov ah,06h ;判断是否有键按下 mov dl,0ffh int 21h pop dx jz lll ;若无则转LLL mov ah,4ch ;返回 int 21h code ends end start ;**********************; ;* 数/模转换实验2 *; ;* 产生正弦波 *; ;**********************; data segment io0832a equ 290h Sin db 80h,96h,0aeh,0c5h,0d8h,0e9h,0f5h,0fdh db 0ffh,0fdh,0f5h,0e9h,0d8h,0c5h,0aeh,96 h db 80h,66h,4eh,38h,25h,15h,09h,04h Db 00h,04h,09h,15h,25h,38h,4eh,66h ;正弦波数据 data ends code segment assume cs:code,ds:data start: mov ax,data mov ds,ax ll: mov si,offset sin ; 置正弦波数据的偏移地址为SI mov bh,32 ;一组输出32个数据 lll: mov al,[si] ;将数据输出到D/A转换器 mov dx,io0832a out dx,al mov ah,06h mov dl,0ffh int 21h jne exit mov cx,1 delay: loop delay ;延时 inc si ;取下一个数据 dec bh jnz lll ;若未取完32个数据则转lll jmp ll exit: mov ah,4ch ;退出 int 21h code ends end start ;****************************; ;* AD转换器2--示波器 *; ;* 采集数据在屏幕是作图 *; ;****************************; io0809b equ 299h code segment assume cs:code start: mov ax,0012h ;设屏幕显示方式为VGA 640X480模示 int 10h start1: mov ax,0600h int 10h ;清屏 and cx,0 ;cx为横坐标draw: mov dx,io0809b ;启动A/D转换器通道1 out dx,al mov bx,200;500 ;延时delay: dec bx jnz delay

总结Selenium WebDriver中一些鼠标和键盘事件的使用

本文将总结Selenium WebDriver 中的一些鼠标和键盘事件的使用,以及组合键的使用,并且将介绍WebDriver 中没有实现的键盘事件(Keys 枚举中没有列举的按键)的扩展。举例说明扩展Alt+PrtSc 组合键来截取当前活动窗口并将剪切板图像保存到文件。 在使用Selenium WebDriver 做自动化测试的时候,会经常模拟鼠标和键盘的一些行为。比如使用鼠标单击、双击、右击、拖拽等动作;或者键盘输入、快捷键使用、组合键使用等模拟键盘的操作。在WebDeriver 中,有一个专门的类来负责实现这些测试场景,那就是Actions 类,在使用该类的过程中会配合使用到Keys 枚举以及Mouse、Keyboard、CompositeAction 等类。 其次,在实际测试过程中,可能会遇到某些按键没办法使用Actions、Keys 等类来实现的情况。比如通过使用Alt+PrtSc 组合键来实现截取屏幕当前活动窗口的图像,在Keys 枚举中,因为没有枚举出PrtSc 键,所以没办法通过Action 的KeyDown(Keys) 来模拟按下这个动作。 再次是在自动化测试中,可能会遇到一些附件、文件上传的场景,或者是多文件上传,这些在Selenium2.0 之后,可以直接使用WebElement 类的sendKeys() 方法来实现。 下面就分别介绍这些情况的具体使用。 鼠标点击操作 鼠标点击事件有以下几种类型: 清单1. 鼠标左键点击 Actions action = new Actions(driver);action.click();// 鼠标左键在当前停留的位置做单击操作 action.click(driver.findElement(https://www.doczj.com/doc/09928644.html,(element)))// 鼠标左键点击指定的元素 清单2. 鼠标右键点击 Actions action = new Actions(driver); action.contextClick();// 鼠标右键在当前停留的位置做单击操作 action.contextClick(driver.findElement(https://www.doczj.com/doc/09928644.html,(element)))// 鼠标右键点击指定的元素 清单3. 鼠标双击操作 Actions action = new Actions(driver); action.doubleClick();// 鼠标在当前停留的位置做双击操作

微机原理实验程序

硬件实验七 D/A转换实验 (2 锯齿波 --------------- ; 注意:进行本实验前, 请先装载运行 D/A 0V输出 (调基准电压程序Asm88\da_0v.asm ; 使 D/A输出端“ AOUT ” 输出电压为 0V , 再进行本实验。 CODE SEGMENT ASSUME CS:CODE,DS:CODE,ES:CODE ORG 33F0H DAPORT EQU 0FFE0H H7: MOV DX,DAPORT MOV AL,00H P7: OUT DX,AL INC AL JMP P7 CODE ENDS END H7 串行通信 CODE SEGMENT ASSUME CS:CODE,DS:CODE,ES:CODE ORG 35C0H ;TX=RX

H11: JMP START Z8251 EQU 0FFE1H D8251 EQU 0FFE0H COM_MOD EQU 04EH COM_COM EQU 25H ZXK EQU 0FFDCH ZWK EQU 0FFDDH LED DB 0C0H,0F9H,0A4H,0B0H,99H,92H,82H,0F8H,80H,90H DB 88H,83H,0C6H,0A1H,86H,8EH,0FFH,0CH,0DEH,0F3H BUF DB ?,?,?,?,?,? START: MOV BX,4000H MOV AL,[BX] CMP AL,00H JNZ SR0 SR8251: MOV DX,Z8251 MOV AL,COM_MOD OUT DX,AL MOV AL,COM_COM OUT DX,AL MOV AL,10

相关主题
文本预览
相关文档 最新文档