关于全画幅和aps-c画幅景深比较

是自己的理解,有任何不对的地方,欢迎交流。 首先先确定影响景深(DOF: Depth Of Field)的因素,根据wikipeida上的景深计算公式(此公式在拍摄距离大于镜头焦距的情况下成立,下面的讨论都是在这种情况下)可以知道: 其中: N是拍摄时镜头的光圈值 c是相机弥散圆直径,而弥散圆与相机的画幅有关系 f是镜头焦距,这里的焦距分为两种情况,后面会分别介绍 s是拍摄距离 可以看到,影响景深的因素有: 光圈大小 画幅大小 镜头焦距 拍摄距离 情况一、当两个一模一样的50mm镜头,在相同的3m距离下,使用相同的f/2.8光圈拍摄时,全画幅和aps-c画幅的景深区别如下(根据上面的公式,写了个景深计算器,本文中所有的景深数值全部来自此计算器): 全画幅景深: aps-c画幅: 结论:情况一下,aps-c画幅要比全画幅景深浅,但可以想象的是,全画幅拍出来的照片视野要广。 情况二、当视野相同的时候,这时镜头焦距就不一样了,假设全画幅(感光元件长度为36mm)上使用75mm的镜头,那么aps-c(感光元件水平长度为24mm)上就要使用50mm的镜头了。光圈还是f/2.8,拍摄距离还是3米: 全画幅景深: aps-c画幅景深: 结论:情况二下,如果拍摄视野相同的照片,那么全副的景深要比aps-c的浅。 两种情况下得出的结论是不一样的。 附加一段视频说明,视频来自youtube,传到了国内的youku上: 视频中摄影师通过实际拍摄将上面的两种情况都进行了说明,不同的是第一种情况下,视频中的图片看不出来aps-c比全画幅景深浅,而第二种情况则可以体现出来。 第一种情况,场景的缘故,看不出来aps-c景深更浅,点击可以看大图: 第二种情况,可以明显看到全画幅景深浅,点击可以看大图: 需要说明的是,视频中是按照1.6倍的关系说明的,而本文是按照1.5倍说明的,能看出差别即可。 在视频结束部分,主持人说一般体育摄影者如果使用aps-c画幅会有优势,因为可以”更接近”被拍摄的物体,也就是赢得的长焦的优势。严格意义上说,这种说法不严谨,因为就拍摄的画面大小而言,aps-c仅仅是取了全画幅中间一部分,也就是视角比全画幅小了,这在视频开始也进行了演示说明(当然,景深是不一样的。)。 就目前来讲,厂家所设计的aps-c画幅相机的像素密度一般都要高于全画幅,所以情况一下,如果将全画幅所拍摄画面裁减为aps-c的视野大小,清晰度是不及aps-c的,如果全画幅像素密度高于aps-c画幅,那么全画幅裁剪后还要比aps-c清晰,那么aps-c画幅相机就没有卖点了。

自己写一个简单的引导程序

学习操作系统应该多动手 操作过程在xp下进行。 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 ;;;;;;;;;;;;;;;;;;;;;;;;文件名boot.asm;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; [ORG 0] jmp 07C0h:start start: mov ax,cs mov ds,ax mov es,ax reset: mov ax,0 mov dl,0 int 13h jc reset read: mov ax,1000h mov es,ax mov bx,0 mov ah,2 mov al,5 mov ch,0 mov cl,2 mov dh,0 mov dl,0 int 13h jc read jmp 1000h:0000 times 510-($-$$) db 0 dw 0AA55h ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;以上是boot.

内核引导启动程序分析

整个内核引导程序有三个文件,分别是bootsect.s,setup.s,head.s,这三个文件是内核源代码中最先被编译的程序。这3个程序完成的主要功能是当计算机加电时引导内核启动,将内核代码加载到内存中,并作一些进入32位保护运行方式前的系统初始化工作。其中bootsect.s和setup.s程序需要使用as86软件来编译,使用的是as86的汇编语言格式,而head.s需要用GNU as来编译,使用的是AT&T格式的汇编语言。 Bootsect.s程序是磁盘引导块程序,编译后会驻留在磁盘的第一个扇区中,在PC加电ROM BIOS自检后,将被BIOS加载到内存0x7C00处进行执行。 Setup.s程序主要用于读取机器的硬件配置参数,并把内核模块system移动到适当的内存位置处。 Head.s程序会被编译连接在system模块的最前部分,主要进行硬件设备的探测设置和内存管理页面的初始化工作。 Bootsect.s分析 当按机箱上的power on的时候,cpu会自动去到bios中地址0xFFFF0处开始执行bios中的代码,除了会进行一些初始化工作,这段代码最主要的是将可启动设备的第一个扇区(bootsect.s)(引导扇区,512字节)读到内存0x07c00处。 当bootsect.s执行时,它已经被读到了0x07c00处,首先它会将自己读到0x90000处,由于bios被设置成了先读到0x7c00的地方,所以这里需要两步。然后再读到0x90000是为了防止后来读入到0x10000处的system模块覆盖掉bootsect.s。将自己读到0x90000处后先会设置一下堆栈(0x9000:0xff00),然后将setup.s读入到紧接着bootsect的地方(0x90200),默认的是从软盘读取的,然后就是取相应磁盘(被当作软盘,写成了hard code)的参数,然后就是利用bios的0x10中断,ah=0x03,将一段话"Loading system…“打印到屏幕上。然后检测要使用哪个根文件系统设备(软盘或者硬盘),具体的方法是判断508,509字节处的根设备号是否被置为1.这两个字节在编译内核的时候可以当作参数来设置,默认的是第二个硬盘。因为Linus当时在自己的机器上面有两个硬盘,而Linux的开发是在第二个硬盘上面进行的。 如果有硬盘的话,就将其参数保存,否则读取每磁道的扇区数来判断是什么类型的软盘(1.2M还是1.4M),也保存其相应参数。 最后执行 jmpi 0,SETUPSEG,跳转到setup.s程序的开始处执行。 这样呢,bootsect.s就完成了自己的使命,其实最重要的就两点,第一个就是加载内核其它的模块,第二个就是将一些重要的参数保存下来,以供以后使用。 Setup.s分析 setup.s会将被bootsect.s读取到0x10000处的system模块移动到0x00000处,这样好象会把中断表给覆盖掉,文件执行到后来会加载中断描述符表,但是idt表却是这个样子的: idt_48: .word 0 .word 0,0 idt表的基地址居然还是0x00000,这里就搞不懂了,因为这个时候0x00000的地方已经是system模块了,所以在真正的重新设置idt表以前,如果出现异常,这里不知道将会出现什么样的情况,这个是0.11设计的一个不足之处。 setup.s会读取大量的参数然后存到0x90000处,也就是说会覆盖bootsect.s,具体的参数分布在《Linux内核完全分析》上有,系统会将第一个硬盘的参数表读到0x90080处,然后再读取第二个硬盘的参数表到0x90090处,然后再去检测到底有没有第二个硬盘,如果没有再将0x90090处的参数表清0,为什么不先检测有没有第二个硬盘,在去决定是否读取参数表到0x90090呢?非要反着来不成?这个也是0.11代码的一个不足之处,造成了次序颠倒。 下面是关于80386保护模式的一些知识。 在16位的实模式下的程序在内存中的布局和操作系统的是混在一起的,也就是说,cpu没有提供对操作系统的保护,这会出很多问题,32为保护模式下,cpu提供的很强大的功能来保护操作系统的代码不被侵犯,我们所要做的就是提供相应的数据,将相应的寄存器初始化,打开A20地址线,然后执行一个跳转指令,cpu就会进入保护模式,对我们的程序进行保护,具体的各位可以在网上找到资料,其中一个方法就是设置gdt以及ldt来保护操作系统以及应用程序,gdt(大小限制在64k以内)也即全局描述符表里包含有全局描述符,每个全局描述符得大小为8字节,所以理论上,一个gdt一共可以有64K/8=8K个全局描述符.其中三个是描述全局性的操作系统的代码段,数据段,其他的一个程序占用一个全局描述符. 系统怎么来确定要使用哪一个全局描述符呢?使用段选择子!下图是段选择子的结构: 其中3-15字节是用来索引gdt来去定某一个全局描述符得,共13位,所以gdt最大长度限制在2^13=64K.但是在这里Linus只将gdt的长度设置为了2K,也就是在 gdt_48: .word 0x800 !这里是0x800,而不是0xFFFF,是因为现在的gdt是临时的,以后还有设置,所以只要够现在用就可以了 .word 512+gdt,0x9 ! 这里由于setup.s是在0x90200处,所以要加上0x200(512)的偏移量。 然后就是为系统进入32为保护模式作准备了,这里就要先初始化gdt,由于现在还没有程序运行,所以只是用了三项(其实是两项),其中,第零项没有使用,第一项描述系统的代码段,第二项描述系统的数据段(堆栈段)。 全局表述符表: gdt: .word 0x0000 !第0个弃用 .word 0x0000 .word 0x0000 .word 0x0000 .word 0x07FF !第1个,第0个用了4个word,所以这里偏移量是0x08 .word 0x0000 !用来描述系统代码段 .word 0x9A00 .word 0x00C0 .word 0x07FF !第2个,偏移量是0x10,也就是16 .word 0x0000 !用来描述系统数据段 .word 0x9200 .word 0x00C0