AT&T汇编与Intel汇编的比较

gcc采用的是AT&T的汇编格式,MS采用Intel的汇编格式.



一 基本语法



语法上主要有以下几个不同.



1、寄存器命名原则



AT&T: %eax



Intel: eax



2、源/目的操作数顺序



AT&T: movl %eax,%ebx



Intel: mov ebx,eax





3、常数/立即数的格式



AT&T: movl $_value,%ebx



Intel: mov eax,_value



把_value的地址放入eax寄存器



AT&T: movl $0xd00d,%ebx



Intel: mov ebx,0xd00d



4、操作数长度标识



AT&T: movw %ax,%bx



Intel: mov bx,ax



5、寻址方式



AT&T: immed32(basepointer,indexpointer,indexscale)



Intel: [basepointer + indexpointer*indexscale + imm32)



Linux工作于保护模式下,用的是32位线性地址,所以在计算地址时不用考虑segmentffset的问题.上式中的地址应为:



imm32 + basepointer + indexpointer*indexscale



下面是一些例子:



1、直接寻址



AT&T: _booga ; _booga是一个全局的C变量



注意加上$是表示地址引用,不加是表示值引用.



注:对于局部变量,可以通过堆栈指针引用.



Intel: [_booga]



2、寄存器间接寻址



AT&T: (%eax)



Intel: [eax]



3、变址寻址



AT&T: _variable(%eax)



Intel: [eax + _variable]



AT&T: _array(,%eax,4)



Intel: [eax*4 + _array]



AT&T: _array(%ebx,%eax,8)



Intel: [ebx + eax*8 + _array]





二 基本的行内汇编



基本的行内汇编很简单,一般是按照下面的格式



asm("statements");



例如:



asm("nop");



asm("cli");



asm 和 __asm__是完全一样的.



如果有多行汇编,则每一行都要加上 "nt"



例如:



asm( "pushl %eaxnt"



"movl $0,%eaxnt"



"popl %eax");



实际上gcc在处理汇编时,是要把asm(…)的内容"打印"到汇编文件中,所以格式控制字符是必要的.



再例如:



asm("movl %eax,%ebx");



asm("xorl %ebx,%edx");



asm("movl $0,_booga);



在上面的例子中,由于我们在行内汇编中改变了edx和ebx的值,但是由于gcc的特殊的处理方法,即先形成汇编文件,再交给GAS去汇编,所以GAS并不知道我们已经改变了edx和ebx的值,如果程序的上下文需要edx或ebx作暂存,这样就会引起严重的后果.对于变量_booga也存在一样的问题.为了解决这个问题,就要用到扩展的行内汇编语法.





三 扩展的行内汇编



扩展的行内汇编类似于Watcom.



基本的格式是:



asm ( "statements" : output_regs : input_regs : clobbered_regs);



clobbered_regs指的是被改变的寄存器.



下面是一个例子(为方便起见,我使用全局变量):



int count=1;



int value=1;



int buf[10];



void main()

{

asm(



"cld nt"



"rep nt"



"stosl":: "c" (count), "a" (value) , "D" (buf[0]): "%ecx","%edi" );



}



得到的主要汇编代码为:



movl count,%ecx



movl value,%eax



movl buf,%edi



#APP



cld



rep



stosl



#NO_APP



cld,rep,stos就不用多解释了.这几条语句的功能是向buf中写上count个value值.冒号后的语句指明输入,输出和被改变的寄存器.通过冒号以后的语句,编译器就知道你的指令需要和改变哪些寄存器,从而可以优化寄存器的分配.其中符号"c"(count)指示要把count的值放入ecx寄存器



类似的还有:



a eax



b ebx



c ecx



d edx



S esi



D edi



I 常数值,(0 – 31)



q,r 动态分配的寄存器



g eax,ebx,ecx,edx或内存变量



A 把eax和edx合成一个64位的寄存器(use long longs)





我们也可以让gcc自己选择合适的寄存器.如下面的例子:



asm("leal (%1,%1,4),%0"



: "=r" (x)



: "0" (x) );



这段代码实现5*x的快速乘法.



得到的主要汇编代码为:



movl x,%eax



#APP



leal (%eax,%eax,4),%eax



#NO_APP



movl %eax,x



几点说明:



1.使用q指示编译器从eax,ebx,ecx,edx分配寄存器.使用r指示编译器从eax,ebx,ecx,edx,esi,edi分配寄存器.



2.我们不必把编译器分配的寄存器放入改变的寄存器列表,因为寄存器已经记住了它们.



3."="是标示输出寄存器,必须这样用.



4.数字%n的用法:数字表示的寄存器是按照出现和从左到右的顺序映射到用"r"或"q"请求的寄存器.如果我们要重用"r"或"q"请求的寄存器的话,就可以使用它们.



5.如果强制使用固定的寄存器的话,如不用%1,而用ebx,则



asm("leal (%%ebx,%%ebx,4),%0"



: "=r" (x)



: "0" (x) );



注意要使用两个%,因为一个%的语法已经被%n用掉了.



下面可以来解释letter 4854-4855的问题:



1、变量加下划线和双下划线有什么特殊含义吗?加下划线是指全局变量,但我的gcc中加不加都无所谓.



2、以上定义用如下调用时展开会是什么意思?



#define _syscall1(type,name,type1,arg1)



type name(type1 arg1)



{



long __res;



/* __res应该是一个全局变量 */



__asm__ volatile ("int $0x80"



/* volatile 的意思是不允许优化,使编译器严格按照你的汇编代码汇编*/



: "=a" (__res)



/* 产生代码 movl %eax, __res */



: "0" (__NR_##name),"b" ((long)(arg1)));



/* 如果我没记错的话,这里##指的是两次宏展开.



  即用实际的系统调用名字代替"name",然后再把__NR_…展开.



  接着把展开的常数放入eax,把arg1放入ebx */



if (__res >= 0)



return (type) __res;



errno = -__res;



return -1;



}

AT&T汇编与Intel汇编的比较

gcc采用的是AT&T的汇编格式,MS采用Intel的汇编格式.



一 基本语法



语法上主要有以下几个不同.



1、寄存器命名原则



AT&T: %eax



Intel: eax



2、源/目的操作数顺序



AT&T: movl %eax,%ebx



Intel: mov ebx,eax





3、常数/立即数的格式



AT&T: movl $_value,%ebx



Intel: mov eax,_value



把_value的地址放入eax寄存器



AT&T: movl $0xd00d,%ebx



Intel: mov ebx,0xd00d



4、操作数长度标识



AT&T: movw %ax,%bx



Intel: mov bx,ax



5、寻址方式



AT&T: immed32(basepointer,indexpointer,indexscale)



Intel: [basepointer + indexpointer*indexscale + imm32)



Linux工作于保护模式下,用的是32位线性地址,所以在计算地址时不用考虑segmentffset的问题.上式中的地址应为:



imm32 + basepointer + indexpointer*indexscale



下面是一些例子:



1、直接寻址



AT&T: _booga ; _booga是一个全局的C变量



注意加上$是表示地址引用,不加是表示值引用.



注:对于局部变量,可以通过堆栈指针引用.



Intel: [_booga]



2、寄存器间接寻址



AT&T: (%eax)



Intel: [eax]



3、变址寻址



AT&T: _variable(%eax)



Intel: [eax + _variable]



AT&T: _array(,%eax,4)



Intel: [eax*4 + _array]



AT&T: _array(%ebx,%eax,8)



Intel: [ebx + eax*8 + _array]





二 基本的行内汇编



基本的行内汇编很简单,一般是按照下面的格式



asm("statements");



例如:



asm("nop");



asm("cli");



asm 和 __asm__是完全一样的.



如果有多行汇编,则每一行都要加上 "\n\t"



例如:



asm( "pushl %eax\n\t"



"movl $0,%eax\n\t"



"popl %eax");



实际上gcc在处理汇编时,是要把asm(…)的内容"打印"到汇编文件中,所以格式控制字符是必要的.



再例如:



asm("movl %eax,%ebx");



asm("xorl %ebx,%edx");



asm("movl $0,_booga);



在上面的例子中,由于我们在行内汇编中改变了edx和ebx的值,但是由于gcc的特殊的处理方法,即先形成汇编文件,再交给GAS去汇编,所以GAS并不知道我们已经改变了edx和ebx的值,如果程序的上下文需要edx或ebx作暂存,这样就会引起严重的后果.对于变量_booga也存在一样的问题.为了解决这个问题,就要用到扩展的行内汇编语法.





三 扩展的行内汇编



扩展的行内汇编类似于Watcom.



基本的格式是:



asm ( "statements" : output_regs : input_regs : clobbered_regs);



clobbered_regs指的是被改变的寄存器.



下面是一个例子(为方便起见,我使用全局变量):



int count=1;



int value=1;



int buf[10];



void main()

{

asm(



"cld \n\t"



"rep \n\t"



"stosl":: "c" (count), "a" (value) , "D" (buf[0]): "%ecx","%edi" );



}



得到的主要汇编代码为:



movl count,%ecx



movl value,%eax



movl buf,%edi



#APP



cld



rep



stosl



#NO_APP



cld,rep,stos就不用多解释了.这几条语句的功能是向buf中写上count个value值.冒号后的语句指明输入,输出和被改变的寄存器.通过冒号以后的语句,编译器就知道你的指令需要和改变哪些寄存器,从而可以优化寄存器的分配.其中符号"c"(count)指示要把count的值放入ecx寄存器



类似的还有:



a eax



b ebx



c ecx



d edx



S esi



D edi



I 常数值,(0 – 31)



q,r 动态分配的寄存器



g eax,ebx,ecx,edx或内存变量



A 把eax和edx合成一个64位的寄存器(use long longs)





我们也可以让gcc自己选择合适的寄存器.如下面的例子:



asm("leal (%1,%1,4),%0"



: "=r" (x)



: "0" (x) );



这段代码实现5*x的快速乘法.



得到的主要汇编代码为:



movl x,%eax



#APP



leal (%eax,%eax,4),%eax



#NO_APP



movl %eax,x



几点说明:



1.使用q指示编译器从eax,ebx,ecx,edx分配寄存器.使用r指示编译器从eax,ebx,ecx,edx,esi,edi分配寄存器.



2.我们不必把编译器分配的寄存器放入改变的寄存器列表,因为寄存器已经记住了它们.



3."="是标示输出寄存器,必须这样用.



4.数字%n的用法:数字表示的寄存器是按照出现和从左到右的顺序映射到用"r"或"q"请求的寄存器.如果我们要重用"r"或"q"请求的寄存器的话,就可以使用它们.



5.如果强制使用固定的寄存器的话,如不用%1,而用ebx,则



asm("leal (%%ebx,%%ebx,4),%0"



: "=r" (x)



: "0" (x) );



注意要使用两个%,因为一个%的语法已经被%n用掉了.



下面可以来解释letter 4854-4855的问题:



1、变量加下划线和双下划线有什么特殊含义吗?加下划线是指全局变量,但我的gcc中加不加都无所谓.



2、以上定义用如下调用时展开会是什么意思?



#define _syscall1(type,name,type1,arg1) \



type name(type1 arg1) \



{ \



long __res; \



/* __res应该是一个全局变量 */



__asm__ volatile ("int $0x80" \



/* volatile 的意思是不允许优化,使编译器严格按照你的汇编代码汇编*/



: "=a" (__res) \



/* 产生代码 movl %eax, __res */



: "0" (__NR_##name),"b" ((long)(arg1))); \



/* 如果我没记错的话,这里##指的是两次宏展开.



  即用实际的系统调用名字代替"name",然后再把__NR_…展开.



  接着把展开的常数放入eax,把arg1放入ebx */



if (__res >= 0) \



return (type) __res; \



errno = -__res; \



return -1; \



}

汇编常用命令

MOV 指令为双操作数指令,两个操作数中必须有一个是寄存器.
  MOV DST , SRC // Byte / Word
  执行操作: dst = src
  1.目的数可以是通用寄存器, 存储单元和段寄存器(但不允许用CS段寄存器).
  2.立即数不能直接送段寄存器
  3.不允许在两个存储单元直接传送数据
  4.不允许在两个段寄存器间直接传送信息
  PUSH 入栈指令及POP出栈指令: 堆栈操作是以"后进先出"的方式进行数据操作.
  PUSH SRC //Word
  入栈的操作数除不允许用立即数外,可以为通用寄存器,段寄存器(全部)和存储器.
  入栈时高位字节先入栈,低位字节后入栈.
  POP DST //Word
  出栈操作数除不允许用立即数和CS段寄存器外, 可以为通用寄存器,段寄存器和存储器.
  执行POP SS指令后,堆栈区在存储区的位置要改变.
  执行POP SP 指令后,栈顶的位置要改变.
  XCHG(eXCHanG)交换指令: 将两操作数值交换.
  XCHG OPR1, OPR2 //Byte/Word
  执行操作: Tmp=OPR1 OPR1=OPR2 OPR2=Tmp
  1.必须有一个操作数是在寄存器中
  2.不能与段寄存器交换数据
  3.存储器与存储器之间不能交换数据.
  XLAT(TRANSLATE)换码指令: 把一种代码转换为另一种代码.
  XLAT (OPR 可选) //Byte
  执行操作: AL=(BX+AL)
  指令执行时只使用预先已存入BX中的表格首地址,执行后,AL中内容则是所要转换的代码.
  LEA(Load Effective Address) 有效地址传送寄存器指令
  LEA REG , SRC //指令把源操作数SRC的有效地址送到指定的寄存器中.
  执行操作: REG = EAsrc
  注: SRC只能是各种寻址方式的存储器操作数,REG只能是16位寄存器
  MOV BX , OFFSET OPER_ONE 等价于 LEA BX , OPER_ONE
  MOV SP , [BX] //将BX间接寻址的相继的二个存储单元的内容送入SP中
  LEA SP , [BX] //将BX的内容作为存储器有效地址送入SP中
  LDS(Load DS with pointer)指针送寄存器和DS指令
  LDS REG , SRC //常指定SI寄存器。
  执行操作: REG=(SRC), DS=(SRC+2) //将SRC指出的前二个存储单元的内容送入指令中指定的寄存器中,后二个存储单元送入DS段寄存器中。
  LES (Load ES with pointer) 指针送寄存器和ES指令
  LES REG , SRC //常指定DI寄存器
  执行操作: REG=(SRC) , ES=(SRC+2) //与LDS大致相同,不同之处是将ES代替DS而已.
  LAHF ( Load AH with Flags ) 标志位送AH指令
  LAHF //将PSW寄存器中的低8位的状态标志(条件码)送入AH的相应位, SF送D7位, ZF送D6位……
  执行操作: AH=PSW的低位字节。
  SAHF ( Store AH into Flags ) AH送标志寄存器指令
  SAHF //将AH寄存器的相应位送到PSW寄存器的低8位的相应位, AH的D7位送SF, D6位送ZF……
  执行操作: PSW的低位字节=AH。
  PUSHF ( PUSH the Flags) 标志进栈指令
  PUSHF //将标志寄存器的值压入堆栈顶部, 同时栈指针SP值减2
  执行操作: SP=SP-1,(SP)=PSW的高8位, SP=SP-1, (SP)=PSW的低8位
  POPF ( POP the Flags ) 标志出栈指令
  POPF //与PUSHF相反, 从堆栈的顶部弹出两个字节送到PSW寄存器中, 同时堆栈指针值加2
  执行操作: PSW低8位=(SP), SP=SP+1, PSW高8位=(SP) , SP=SP+1
  输入输出指令(IN,OUT):只限于使用累加器AX或AL与外部设备的端口传送信息.
  IN (INput)输入指令:信息从I/O通过累加器传送到CPU
  IN AL , PORT //直接的字节输入,PORT是外设端口编号(即端口地址),只能取 00H ~ 0FFH共256个端口地址.
  IN AX , PORT //直接的字输入,AX存储连续两个端口地址PORT+1,PORT
  IN AL , DX //间接的字节输入,端口地址范围可通过DX设置为0000H ~ 0FFFFH共65536个端口地址
  IN AX , DX //间接的字输入
  OUT( OUTput)输出指令 :信息从CPU通过累加器传送到I/O
  OUT PORT , AL //直接的字节输出,PORT规定与IN指令相同.
  OUT PORT , AX
  OUT DX , AL //间接的字节输出
  OUT DX , AX
  MOV AL,05H OUT 27H, AL //将字节05H传送到地址27H的端口
  ADD(ADD)加法指令
  ADD DST , SRC //Byte/Word
  执行操作: dst=dst+src
  1.两个存储器操作数不能通过ADD指令直接相加, 即DST 和SRC必须有一个是通用寄存器操作数.
  2.段寄存器不能作为SRC 和DST.
  3.影响标志位Auxiliary Crray Flag ,Carry Flag, Overflow Flag, Parity Flag, Sign Flag 和Zero Flag ,如下所示:
  CF 根据最高有效位是否有进(借)位设置的:有进(借)位时CF=1, 无进(借)位时CF=0.
  OF 根据操作数的符号及其变化来设置的:若两个操作数的符号相同,而结果的符号与之相反时OF=1, 否则为0.
  ZF 根据结果来设置:不等于0时ZF=0, 等于0时ZF=1
  SF 根据结果的最高位来设置:最高位为0, 则SF=0.
  AF 根据相加时D3是否向D4进(借)位来设置:有进(借)位时AF=1, 无进(借)位时AF=0
  PF 根据结果的1的个数时否为奇数来设置:1的个数为奇数时PF=0, 为偶数时PF=1
  ADC( ADd with Carry)带进位加法指令
  ADC DST , SRC //Byte/Word
  执行操作: dst=dst+src+CF //与ADD不同之处是还要加上进位标志位的值.
  INC ( INCrement) 加1指令
  INC OPR //Byte/Word
  执行操作: OPR=OPR+1
  1.OPR可以是寄存器和存储器操作数, 但不能是立即数和段寄存器
  2.影响标志位OF,SF,ZF,PF 和AF,不影响CF.
  SUB ( SUBtract ) 不带借位的减法指令
  SUB DST , SRC //Byte/Word
  执行操作:dst=dst – src
  1.DST和SRC寻址方式及规定与ADD相同.
  2.影响全部标志位.(判断标志位参见ADD)
  SBB ( SuBtract with Borrow) 带借位减法指令
  SBB DST , SRC //Byte/Word
  执行操作:dst= dst – src – CF
  DEC ( DECrement ) 减1指令
  DEC OPR //Byte/Word
  执行操作:OPR = OPR – 1 //除CF标志位, 其余标志位都受影响.
  NEG ( NEGate ) 求补指令
  NEG OPR
  执行操作:opr = 0- opr //将操作数按位求反后末位加1.
  CMP ( CoMPare ) 比较指令
  CMP OPR1 , OPR2
  执行操作:OPR1 – OPR2 //与SUB指令一样执行运算, 但不保存结果.
  比较情况 无符号数 有符号数
  A=B ZF=1 ZF=1
  A>B CF=0 && ZF=0 SF^OF=0 && ZF=0
  A<B CF=1 && ZF=0 SF^OF=1 && ZF=0
  A>=B CF=0 || ZF=1 SF^OF=0 || ZF=1
  A<=B CF=1 || ZF=1 SF^OF=1 || ZF=1
  MUL ( unsigned MULtiple ) 无符号数乘法指令
  MUL SRC //Byte/Word .
  执行操作:Byte => AX= AL *src //字节运算时目的操作数用AL, 乘积放在AX中
  Word => DX=AX *src //字运算时目的操作数用AX, DX存放乘积的高位字, AX放乘积的低位字
  1.目的数必须是累加器 AX 或AL,指令中不需写出
  2. 源操作数SRC可以是通用寄存器和各种寻址方式的存储器操作数, 而绝对不允许是立即数或段寄存器.
  IMUL (sIgned MULtiple) 有符号数乘法指令
  IMUL SRC //与MUL指令相同,但必须是带符号数
  DIV ( unsigned DIVide) 无符号数除法指令
  DIV SRC //Byte/Word 其中: SRC的规定同乘法指令MUL
  执行操作:Byte => AX / src //字节运算时目的操作数在AX中,结果的商在AL中 ,余数中AH中
  Word=> DX,AX /src //字运算时目的操作数在DX高位字和AX低位字中,结果的商在AX中 ,余数在DX中
  存储器操作数必须指明数据类型:BYTE PTR src 或 WORD PTR src
  IDIV (sIgned DIVied) 有符号数除法指令
  IDIV SRC //Byte/Word 与DIV指令相同,但必须是带符号数
  CBW (Convert Byte to Word) 字节转换为字指令
  CBW
  执行操作: AL中的符号位(D7)扩展到8位AH中,若AL中的D7=0,则AH=00H,若AL中的D7=1,则AH=FFH.
  CWD (Convert Word to Double word) 字转换为双字指令
  CWD
  执行操作: AX中的符号位(D15)扩展到16位DX中,若AX中的D15=0,则DX=0000H,若AX中的D15=1,则DX=FFFFH
  十进制调整指令
  当计算机进行计算时,必须先把十进制数转换为二进制数,再进行二进制数运算,最后将结果又转换为十进制数输出.
  在计算机中,可用4位二进制数表示一位十进制数,这种代码称为BCD ( Binary Coded Decimal ).
  BCD码又称8421码,在PC机中,BCD码可用压缩的BCD码和非压缩的BCD码两种格式表示.
  压缩的BCD码用4位二进制数表示一个十制数,整个十进数形式为一个顺序的以4位为一组的数串.
  非压缩的BCD码以8位为一组表示一个十进制数,8位中的低4位表示8421的BCD码,而高4位则没有意义.
  压缩的BCD码调整指令
  DAA (Decimal Adjust for Addition) 加法的十进制调整指令
  DAA
  执行操作:执行之前必须先执行ADD或ADC指令,加法指令必须把两个压缩的BCD码相加,并把结果存话在AL寄存器中.
  DAS (Decimal Adjust for Subtraction) 减法的十进制调整指令
  DAS
  执行操作:执行之前必须先执行SUB或SBB指令,减法指令必须把两个压缩的BCD码相减,并氢结果存放在AL寄存器中.
  非压缩的BCD码调整指令
  AAA (ASCII Adjust for Addition) 加法的ASCII调整指令
  AAA
  执行操作:执行之前必须先执行ADD或ADC指令,加法指令必须把两个非压缩的BCD码相加,并把结果存话在AL寄存器中.
  AAS (ASCII Adjust for Subtraction) 减法的ASCII调整指令
  AAS
  执行操作:执行之前必须先执行SUB或SBB指令,减法指令必须把两个非压缩的BCD码相减,并氢结果存放在AL寄存器中.
  MOVS ( MOVe String) 串传送指令
  MOVB //字节串传送 DF=0, SI = SI + 1 , DI = DI + 1 ;DF = 1 , SI = SI – 1 , DI = DI – 1
  MOVW //字串传送 DF=0, SI = SI + 2 , DI = DI + 2 ;DF = 1 , SI = SI – 2 , DI = DI – 2
  执行操作:[DI] = [SI] ,将位于DS段的由SI所指出的存储单元的字节或字传送到位于ES段的由DI 所指出的存储单元,再修改SI和DI, 从而指向下一个元素.
  在执行该指令之前,必须预置SI和DI的初值,用STD或CLD设置DF值.
  MOVS DST , SRC //同上,不常用,DST和SRC只是用来用类型检查,并不允许使用其它寻址方式来确定操作数.
  1.目的串必须在附加段中,即必须是ES:[DI]
  2.源串允许使用段跨越前缀来修饰,但偏移地址必须是[SI].
  STOS (STOre into String) 存入串指令
  STOS DST
  STOSB //存放字节串 ( DI ) = AL
  STOSW //存放字串 ( DI ) = AX
  执行品作:把AL或AX中的内容存放由DI指定的附加段的字节或字单元中,并根据DF值修改及数据类型修改DI的内容.
  1.在执行该指令之前,必须把要存入的数据预先存入AX或AL中,必须预置DI的初值.
  2.DI所指向的存储单元只能在附加段中,即必须是ES:[DI]
  LODS ( LOaD from String ) 从串取指令
  LODS SRC
  LODSB //从字节串取 AL=(SI)
  LODSW //从字串取 AX= (SI±1) (SI)
  执行操作:把由SI指定的数据段中字节或字单元的内容送入AL或AX中,并根据DF值及数据类型修改SI的内容.
  1.在执行该指令之前,要取的数据必须在存储器中预先定义(用DB或DW),必须预置SI的初值.
  2.源串允许使用段超越前缀来改变数据存储的段区.
  REP (REPeat)重复操作前缀
  REP String Primitive //其中:String Primitive可为MOVS,STOS或LODS指令
  执行操作:使REP前缀后的串指令重复执行,每执行一次CX=CX-1,直至CX=0时退出REP.
  方向标志设置
  CLD (CLear Direction flag) 清除方向标志指令
  CLD
  执行操作:令DF=0, 其后[SI],[DI]执行增量操作
  STD (SeT Direction flag) 设置方向标志指令
  STD
  执行操作:令DF=1, 其后[SI],[DI]执行减量操作
  CMPS (CoMPare String) 串比较指令
  CMPS SRC , DST
  CMPSB //字节串比较 (SI)-(DI)
  CMPSW //字串比较 (SI+1)(SI) – (DI+1)(DI)
  执行操作:把由SI指向的数据段中的一个字节或字与由DI指向的附加段中的一个字节或字相减,不保留结果,只根据结果置标志位.
  SCAS (SCAn String ) 串扫描指令
  SCAS DST
  SCASB
  SCASW
  执行操作:把AX或AL的内容与由DI指向的在附加段中的一个字节或字相减,不保留结果,根据结果置标志位.
  AND, OR , XOR 和 TEST都是双字节操作指令,操作数的寻址方式的规定与算术运算指令相同.
  NOT是单字节操作指令,不允许使用立即数.
  逻辑运算均是按位进行操作,真值表如下:
  AND (位与&) OR ( 位或| ) XOR ( 位异或^ )
  1 & 1 = 1 1 | 1 = 1 1 ^ 1 = 0
  1 & 0 = 0 1 | 0 = 1 1 ^ 0 = 1
  0 & 1 = 0 0 | 1 = 1 0 ^ 1 = 1
  0 & 0 = 0 0 | 0 = 0 0 ^ 0 = 0
  A:逻辑运算指令
  AND (and) 逻辑与指令
  AND DST , SRC //Byte/Word
  执行操作:dst = dst & src
  1.AND指令执行后,将使CF=0,OF=0,AF位无定义,指令执行结果影响SF,ZF和PF标志位.
  2.AND指令典型用法A:用于屏蔽某些位,即使某些位为0.
  屏蔽AL的高4位:即将高4位和0000B相与,低4位和1111B相与
  MOV AL , 39H //AL= 0011 1001B[39H]
  ADD AL , 0FH // AL= 0000 1001B[09H] 即0011 1001B[39H] & 0000 1111B[0FH] = 0000 1001B[09H]
  3.AND指令典型用法B:取出某一位的值(见TEST)
  OR (or) 逻辑或指令
  OR DST , SRC //Byte/Word
  执行操作:dst = dst | src
  1.OR指令执行后,将使CF=0, OF=0, AF位无定义,指令执行结果影响SF, ZF和PF标志位.
  2.常用于将某些位置1.
  将AL的第5位置1:
  MOV AL , 4AH // AL=0100 1010B[4AH]
  OR AL , 10H // AL=0101 1010B[5AH] 即0100 1010B[4AH] | 0001 0000B[10H] =0101 1010B [5AH]
  XOR (eXclusive OR) 逻辑异或指令
  XOR DST , SRC //Byte/Word
  执行操作:dst = dst ^ src
  1.XOR指令常用于使某个操作数清零,同时使CF=0,清除进位标志.
  2.XOR指令使某些位维持不变则与 ‘0’ 相异或,若要使某些位取反则与 ‘1’相异或.
  将AL的高4位维持不变,低4位取反:
  MOV AL, B8H //AL=1011 1000B[B8H]
  XOR AL, 0FH //AL=1011 0111B[B7H] 即1011 1000B[B8H] ^ 0000 1111[0FH]=1011 0111B[B7H]
  测试某一个操作数是否与另一确定操作数相等:
  XOR AX , 042EH
  JZ …. //如果AX==042EH, 则ZF=TRUE(1), 执行JZ…
  NOT (not) 逻辑非指令
  NOT OPR //Byte/Word
  执行操作:opr = ~opr // ~ 01100101 [65H] =10011010 [9AH]
  1.操作数不能使用立即数或段寄存器操作数,可使用通用寄存器和各种方式寻址的存储器操作数.
  2.NOT指令不影响任何标志位。
  将AL各位取反:
  MOV AL,65H //AL=0110 0101B[65H]
  NOT AL //AL=1001 1010B[9AH] 即 ~ 0110 0101B[65H]=1001 1010B[9AH]
  TEST (test) 指令
  TEST OPR1 , OPR2 //Byte/Word
  执行操作:opr1 & opr2
  1.两个操作数相与的结果不保存,结果影响标志位PF,SF和ZF,使CF=0, OF=0,而AF位无定义.
  2.TEST指令常用于在不改变原有的操作数的情况下,检测某一位或某几位的条件是否满足.只要令用来测试的操作数对应检测位为1,其余位为0,相与后判断零标志ZF值的真假.
  检测某位是否为1:
  令用来测试的操作数对应检测位为1,其余位为0,TEST指令后,若该位为1则 JNZ…
  TEST AL , 0000 00001B //测试AL最低位是否为1:: 令用来测试的操作数对应检测位为1,其余位为0,执行TEST指令
  JNZ THER //最低位若为1, 则ZF=FALSE(0), 执行JNZ THER, 否则执行下一条指令.
  或者:先对操作数求反,令用来测试的操作数对应检测位为1,其余位为0,TEST指令后,若该位为1则JZ…
  MOV DL , AL //将AL 传送到DL,主要是不要影响AL的值. 以下测试AL的b2位是否为1
  NOT DL //先对操作数求反
  TEST 0000 0100B //令用来测试的操作数对应检测位为1,其余位为0,执行TEST指令
  JZ THER //若AL的b2位为1,则ZF=TRUE(1), 执行JZ THER
  B:移位指令[所有的移位指令都影响标志位CF、OF、PF、SF和ZF.AF无定义.]
  非循环逻辑移位:把操作数看成无符数来进行移位.
  SHL ( SHift logical Left )逻辑左移指令
  SHL OPR , CNT //Byte/Word
  执行操作:使OPR左移CNT位,并使最低CNT位为全0.
  1.OPR操作数不能使用立即数或段寄存器操作数,可使用通用寄存器和各种方式寻址的存储器操作数.
  2.移位次数由CNT决定.每次将OPR的最高位移出并移到CF,最低位补0.
  MOV CL , 7 //若移位多次, 先预置移位次数CL
  SHL DX , CL //CNT可取1或CL寄存器操作数
  SHR (SHift logical Right) 逻辑右移指令
  SHR OPR , CNT //Byte/Word
  同SHL,每次将OPR的最低位D0移出并移到CF.最高位补0.
  非循环算术移位:将操作数看成有符号数来进行移位.
  SAL (Shift Arithmetic Left) 算术左移指令
  SAL OPR , CNT //Byte/Word
  SAL指令与SHL指令完全相同
  SAR(Shift Arithmetic Right) 算术右移指令
  SAR OPR , CNT //Byte/Word
  SAR指令每次移位时,将最高位移入次高位的同时最高位值不变,最低位D0移出并移到CF.
  循环移位指令
  ROL ( ROtate Left) 循环左移指令
  ROL OPR , CNT //Byte/Word
  每次移位时,最高位移出并同时移到CF和最低位D0.
  ROR (ROtate Right)循环右移指令
  ROR OPR,CNT //Byte/Word
  每次移位时,最低位D0移出并同时移到CF和最高位.
  带进位循环移位指令
  RCL (Rotate Left through Carry)带进位循环左移指令
  RCL OPR,CNT //Byte/Word
  RCR (Rotate Right through Carry)带进位循环右移指令
  RCR OPR ,CNT //Byte/Word
  处理器控制指令
  CLC (CLear Carry) 进位位置0指令
  CLC //执行操作后,CF=0
  CMC (CoMplement Carry) 进位位求反指令
  CMC //执行操作后,CF=!CF
  STC (SeT Carry) 进位位置1指令
  STC //执行操作后,CF=1
  NOP (No Operetion) 无操作指令
  NOP //此指令不执行任何操作,其机器码占一个字节单元
  HLT (HaLT) 停机指令
  HLT
  执行操作后,使机器暂停工作,使处理器CPU处于停机状态,以等待一次外部中断到来,中断结束后,程序继续执行,CPU继续工作.
  JMP ( JuMP ) 无条件转移指令
  名称 格式 执行操作
  段内直接短跳转 JMP SHORT OPR IP=IP+8 位偏移量
  段内直接近转移 JMP NEAR PTR OPR IP=IP+16位偏移量
  段内间接转移 JMP WORD PTR OPR IP=(EA)
  段间直接转移 JMP FAR PTR OPR IP=OPR 偏移地址, CS=OPR 段地址
  段间间接转移 JMP DWORD PTR OPR IP=(EA),CS=(EA+2)
  1.无条件转移到指定的地址去执行从该地址开始的指令.
  2.段内转移是指在同一代码段的范围内进行转移,只需改变IP寄存器内容.
  3.段间转移则要转移到另一个代码段执行程序,此时要改变IP寄存器和CS段寄存器的内容.
  条件转移指令:根据上一条指令所设置的条件码(标志位)来判断测试条件.
  根据五个标志位:ZF、SF、OF、 PF、 CF的两种状态(0 FALSE或1 TRUE)产生10种测试条件.
  Name Flag Flag == TRUE [1] Flag ==FALSE [ 0]
  Zero Falg ZF JE/JZ OPR //结果为零转移 JNE/JNZ OPR //结果不为零转移
  Sign Falg SF JS OPR //结果为负转移 JNS OPR //结果为正转移
  Overflow Flag OF JO OPR //溢出转移 JNO OPR //不溢出转移
  Parity Flag PF JP/JPE OPR //结果为偶转移 JNP/JPO OPR //结果为奇转移
  Carry Flag CF JC OPR //有进位转移 JNC OPR //无进位转移
  两个数比较:
  情况 指令 满足条件 指令 满足条件
  A < B JC CF==1 JL SF^OF==1 && ZF==0
  A ≥ B JNC CF==0 JNL SF^OF==0 || ZF==1
  A ≤ B JNA CF==1 || ZF==1 JLG SF^OF==1 || ZF==1
  A > B JA CF==0 && ZF==0 JG SF^OF==0 && ZF==0
  测试CX转移指令
  JCXZ OPR //CX==0时转移
  LOOP(LOOP)循环指令
  LOOP OPR 测试条件:CX ≠ 0 //OPR在程序中实际是个标号
  LOOPZ OPR 测试条件:ZF == 1 && CX ≠ 0
  LOOPNZ OPR 测试条件:ZF == 0 && CX ≠ 0
  执行操作: 先执行CX=CX-1,再检测上面的测试条件,如满足则IP=IP+符号扩展的D8,不满足则退出循环.
  过程调用及返回指令
  CALL (CALL) 过程调用指令
  CALL DST //DST在程序中实际是子程序标号
  执行操作:先将过程的返回地址(即CALL的下一条指令的首地址)存入堆栈,然后转移到过程入口地址执行子程序.
  调用方式 格式 断点保护入栈情况 过程入口地址
  段内直接 CALL NEAR PTR PR1 (SP-1)(SP-2)←IP , CS不进栈 CS值保持不变,IP←DST
  段内间接 CALL WORD PTR (EA) (SP-1)(SP-2)←IP , CS不进栈 CS值保持不变,IP←(EA)
  段间直接 CALL FAR PTR PR1 (SP-1)(SP-2)←CS , (SP-3)(SP-4)←IP IP←DST偏移地址,CS←DST段地址
  段间间接 CALL DWORD PTR (EA) (SP-1)(SP-2)←CS , (SP-3)(SP-4)←IP IP←(EA),CS←(EA+2)
  注:为了表明是段内调用,可使用NEAR PTR属性操作符作说明.
  RET(RETurn)子程序返回指令
  RET
  RET EXP //带立即数返回
  子程序返回指令RET放在子程序末尾,它使子程序在执行完全部任务后返回主程序继续执行被打断后的程序.返回地址在子程序调用时入栈保存的断点地址-IP或IP和CS.

Iptable配置

cnscn大哥,小弟不才,想在你这里发表一个我写的关于IPTABLES的文章,如有不对的地方还请大哥提出!

linux下IPTABLES配置详解
如果你的IPTABLES基础知识还不了解,建议先去看看.
开始配置
我们来配置一个filter表的防火墙.
(1)查看本机关于IPTABLES的设置情况
[root@tp ~]# iptables -L -n
Chain INPUT (policy ACCEPT)
target prot opt source destination
Chain FORWARD (policy ACCEPT)
target prot opt source destination
Chain OUTPUT (policy ACCEPT)
target prot opt source destination
Chain RH-Firewall-1-INPUT (0 references)
target prot opt source destination
ACCEPT all — 0.0.0.0/0 0.0.0.0/0
ACCEPT icmp — 0.0.0.0/0 0.0.0.0/0 icmp type 255
ACCEPT esp — 0.0.0.0/0 0.0.0.0/0
ACCEPT ah — 0.0.0.0/0 0.0.0.0/0
ACCEPT udp — 0.0.0.0/0 224.0.0.251 udp dpt:5353
ACCEPT udp — 0.0.0.0/0 0.0.0.0/0 udp dpt:631
ACCEPT all — 0.0.0.0/0 0.0.0.0/0 state RELATED,ESTABLISHED
ACCEPT tcp — 0.0.0.0/0 0.0.0.0/0 state NEW tcp dpt:22
ACCEPT tcp — 0.0.0.0/0 0.0.0.0/0 state NEW tcp dpt:80
ACCEPT tcp — 0.0.0.0/0 0.0.0.0/0 state NEW tcp dpt:25
REJECT all — 0.0.0.0/0 0.0.0.0/0 reject-with icmp-host-prohibited
可以看出我在安装linux时,选择了有防火墙,并且开放了22,80,25端口.
如果你在安装linux时没有选择启动防火墙,是这样的
[root@tp ~]# iptables -L -n
Chain INPUT (policy ACCEPT)
target prot opt source destination
Chain FORWARD (policy ACCEPT)
target prot opt source destination
Chain OUTPUT (policy ACCEPT)
target prot opt source destination
什么规则都没有.
(2)清除原有规则.
不管你在安装linux时是否启动了防火墙,如果你想配置属于自己的防火墙,那就清除现在filter的所有规则.
[root@tp ~]# iptables -F 清除预设表filter中的所有规则链的规则
[root@tp ~]# iptables -X 清除预设表filter中使用者自定链中的规则
我们在来看一下
[root@tp ~]# iptables -L -n
Chain INPUT (policy ACCEPT)
target prot opt source destination
Chain FORWARD (policy ACCEPT)
target prot opt source destination
Chain OUTPUT (policy ACCEPT)
target prot opt source destination
什么都没有了吧,和我们在安装linux时没有启动防火墙是一样的.(提前说一句,这些配置就像用命令配置IP一样,重起就会失去作用),怎么保存.
[root@tp ~]# /etc/rc.d/init.d/iptables save

这样就可以写到/etc/sysconfig/iptables文件里了.写入后记得把防火墙重起一下,才能起作用.
[root@tp ~]# service iptables restart

现在IPTABLES配置表里什么配置都没有了,那我们开始我们的配置吧
(3)设定预设规则
[root@tp ~]# iptables -p INPUT DROP
[root@tp ~]# iptables -p OUTPUT ACCEPT
[root@tp ~]# iptables -p FORWARD DROP
上面的意思是,当超出了IPTABLES里filter表里的两个链规则(INPUT,FORWARD)时,不在这两个规则里的数据包怎么处理呢,那就是DROP(放弃).应该说这样配置是很安全的.我们要控制流入数据包
而对于OUTPUT链,也就是流出的包我们不用做太多限制,而是采取ACCEPT,也就是说,不在着个规则里的包怎么办呢,那就是通过.
可以看出INPUT,FORWARD两个链采用的是允许什么包通过,而OUTPUT链采用的是不允许什么包通过.
这样设置还是挺合理的,当然你也可以三个链都DROP,但这样做我认为是没有必要的,而且要写的规则就会增加.但如果你只想要有限的几个规则是,如只做WEB服务器.还是推荐三个链都是DROP.
注:如果你是远程SSH登陆的话,当你输入第一个命令回车的时候就应该掉了.因为你没有设置任何规则.
怎么办,去本机操作呗!
(4)添加规则.
首先添加INPUT链,INPUT链的默认规则是DROP,所以我们就写需要ACCETP(通过)的链
为了能采用远程SSH登陆,我们要开启22端口.
[root@tp ~]# iptables -A INPUT -p tcp –dport 22 -j ACCEPT
[root@tp ~]# iptables -A OUTPUT -p tcp –sport 22 -j ACCEPT (注:这个规则,如果你把OUTPUT 设置成DROP的就要写上这一部,好多人都是望了写这一部规则导致,始终无法SSH.在远程一下,是不是好了.
其他的端口也一样,如果开启了web服务器,OUTPUT设置成DROP的话,同样也要添加一条链:
[root@tp ~]# iptables -A OUTPUT -p tcp –sport 80 -j ACCEPT ,其他同理.)
如果做了WEB服务器,开启80端口.
[root@tp ~]# iptables -A INPUT -p tcp –dport 80 -j ACCEPT
如果做了邮件服务器,开启25,110端口.
[root@tp ~]# iptables -A INPUT -p tcp –dport 110 -j ACCEPT
[root@tp ~]# iptables -A INPUT -p tcp –dport 25 -j ACCEPT
如果做了FTP服务器,开启21端口
[root@tp ~]# iptables -A INPUT -p tcp –dport 21 -j ACCEPT
[root@tp ~]# iptables -A INPUT -p tcp –dport 20 -j ACCEPT
如果做了DNS服务器,开启53端口
[root@tp ~]# iptables -A INPUT -p tcp –dport 53 -j ACCEPT
如果你还做了其他的服务器,需要开启哪个端口,照写就行了.
上面主要写的都是INPUT链,凡是不在上面的规则里的,都DROP
允许icmp包通过,也就是允许ping,
[root@tp ~]# iptables -A OUTPUT -p icmp -j ACCEPT (OUTPUT设置成DROP的话)
[root@tp ~]# iptables -A INPUT -p icmp -j ACCEPT (INPUT设置成DROP的话)

允许loopback!(不然会导致DNS无法正常关闭等问题)
IPTABLES -A INPUT -i lo -p all -j ACCEPT (如果是INPUT DROP)

我的ubuntu

咳。。。都好久没有上我的ubuntu系统了。最近对linux学习的也少了很多。。。都在搞那个可恶的J2ME,不过还算有点成就感,,,今天终于把那环境给搭好了。。这个可废了我不少时间呢。。可恶的小日本,,,搞个手机模拟器还这么郁闷。。。更关键的是api讲得太不详细了。。。还有就是自己对日文一无所知,搞得我想找点资料都不容易。。在中文搜索里根本找不到任何的资料。。。我就自己慢慢琢磨了咯。。花了我好长时间阿。。。还好OK了。。下星期就可以开始写程序。。

linux下挂载U盘等设备

mount命令:

首先用dmesg命令,查看新加载的设备。

然后用mount -t vfat /dev/sdb1 /mount/usb1

指定挂载字符集:

mount -t vfat -o iocharset=gb2312 /dev/sdb1 /mount/usb1

-0选项指定字符集。

指定用户组和用户

mount /dev/sdb1 /mount/usb1/ -t vfat -o iocharset=utf8,uid=ftp,gid=ftp,ro

-t指明挂载的文件类型,优盘一般为vfat格式。

光驱可以直接挂载

mount /dev/cdrom /mount/cdrom

弹出光驱用 eject命令

关闭光驱用 eject -t

自动挂载

autofs

在/dev目录下有一个auto.master文件,它就是一个自动装载文件

把auto.misc文件指定的设备装载到/misc目录

打开/etc/auto.misc文件

编辑加入一行:

Java代码 复制代码
  1. usb              -fstype=vfat             :/dev/sdc1  

然后重启autofs服务

service autofs restart

然后进入/misc/usb目录即可看到优盘内容

挂载windows共享文件

mount -t smbfs -o iocharset=utf8,username=Windows共享用户名,password=密码 -l //IP地址/共享文件夹名 Linux中的挂接点

linux解压方法大全

在Solaris环境下,
压缩的过程 打包tar >> 压缩gzip
解压的过程 解压gzip >> 解包tar

.tar
解包:tar xvf FileName.tar
打包:tar cvf FileName.tar DirName
(注:tar是打包,不是压缩!)

.gz
解压1:gunzip FileName.gz
解压2:gzip -d FileName.gz
压缩:gzip FileName.tar

.tar.gz 和 .tgz
解压:tar zxvf FileName.tar.gz
压缩:tar zcvf FileName.tar.gz DirName

.bz2
解压1:bzip2 -d FileName.bz2
解压2:bunzip2 FileName.bz2
压缩: bzip2 -z FileName

.tar.bz2
解压:tar jxvf FileName.tar.bz2
压缩:tar jcvf FileName.tar.bz2 DirName

.bz
解压1:bzip2 -d FileName.bz
解压2:bunzip2 FileName.bz
压缩:…

.tar.bz
解压:tar jxvf FileName.tar.bz
压缩:…

.Z
解压:uncompress FileName.Z
压缩:compress FileName

.tar.Z
解压:tar Zxvf FileName.tar.Z
压缩:tar Zcvf FileName.tar.Z DirName

.zip
解压:unzip FileName.zip
压缩:zip FileName.zip DirName

.rar
解压:rar x FileName.rar
压缩:rar a FileName.rar DirName

rar请到:http://www.rarsoft.com/download.htm 下载!
解压后请将rar_static拷贝到/usr/bin目录(其他由$PATH环境变量指定的目录也可以):
# cp rar_static /usr/bin/rar

.lha
解压:lha -e FileName.lha
压缩:lha -a FileName.lha FileName

lha请到:http://www.infor.kanazawa-it.ac.jp/~ishii/lhaunix/下载!
解压后请将lha拷贝到/usr/bin目录(其他由$PATH环境变量指定的目录也可以):
# cp lha /usr/bin/

.rpm
解包:rpm2cpio FileName.rpm | cpio -div

.deb
解包:ar p FileName.deb data.tar.gz | tar zxf -

.tar .tgz .tar.gz .tar.Z .tar.bz .tar.bz2 .zip .cpio .rpm .deb .slp .arj .rar .ace .lha .lzh .lzx .lzs .arc .sda .sfx .lnx .zoo .cab .kar .cpt .pit .sit .sea
解压:sEx x FileName.*
压缩:sEx a FileName.* FileName

sEx只是调用相关程序,本身并无压缩、解压功能,请注意!
sEx请到:
http://sourceforge.net/projects/sex下载!
解压后请将sEx拷贝到/usr/bin目录(其他由$PATH环境变量指定的目录也可以):
# cp sEx /usr/bin/

备份和恢复实用工具(Solaris)
tar
dd
cpio
pax

tar –创建磁带和文件存档,恢复文件和目录
tar 命令在很多 UNIX 平台上都可找到。它是一个用于将文件存档到磁带上的快速易用的工具。tar 也可以用于将多个文件存档为一个文件(也就是 tar 文件),使之可以移植到其他系统上使用。例如,如果需要,可以将整个用户主目录或安装目录复制到单个 tar 文件中,并在必要时将其移动到运行 HP-UX 的服务器上。

tar 命令有很多可用的选项,但是我将只讨论用于创建、提取或恢复的三个选项,并列出 tar 文件内容的选项。

tar 命令选项
-c: 创建 tar 文件
-t: 列出 tar 的内容
-x: 提取或恢复 tar 文件内容
-v: Verbose (显示 tar 所采取的动作)

tar 命令的基本语法如下:
tar <options>; <tar filename>; <file list>;
注意: 有时您将在一些 tar 命令例子中看到在选项前使用了破折号,这对于 tar 的正确运行不是必需的。
创建新的 tar 文件:

% tar
cvf filename.tar filelist
在这里,filename.tar 是 tar 文件的名字。filelist 是想要备份的文件列表。可以使用通配符指定列表。

列出 tar 文件的内容:
% tar tvf filename.tar filelist
在这里, filename.tar 可以被一个磁带设备文件所取代。例如:
% tar cvf filename.tar /dev/rmt/0mn

提取 tar 文件内容到当前位置:
% tar xvf filename.tar

dd — 转换和复制文件
dd 命令通常用于将整个文件系统复制到另一个文件系统,或者将硬盘驱动器的内容复制到另一块硬盘。dd 还可以用于将文件系统复制到磁带,反之亦可。dd 是一个相对较快的复制工具:它在传输数据时为数据创建一个精准的副本(字节对字节)。dd 可使用几个选项来指定缓冲区大小、块大小和数据转换。其基本的语法是:

dd <inputfile>;= <outputfile>;= options

下面的例子将整个 c0t1d0s2 的内容复制到第二块磁盘(c0t4d0s2)上,使用的块大小是 128。如果您有可用的剩余磁盘空间并且希望有准备好的备份磁盘以在灾难发生时换出,这会工作得极佳。在这个例子中指定了 slice 2,因为它在 Solaris 操作系统中代表整个磁盘。

% dd if=/dev/rdsk/c0t1d0s2 of=/dev/rdsk/c0t4d0s2 bs=128

要将一台磁带设备上的内容复制到另一台上,使用下面例子所示的命令。(注意:必须有两台可用驱动器。)

% dd if=/dev/rmt/#1drive of=/dev/rmt/#2drive
有关 dd 的 man 页面给出了很多其他可用的选项。我建议您查看 dd 的 man 页面并且阅读 Notes 小节。在那里,您将发现 dd 的一些限制,以及在从磁盘设备复制数据时使用裸字符设备的一个提示。

cpio –拷入和拷出文件存档
cpio 代表“拷入,拷出”,用于从一个位置复制数据到另一个位置。使用 cpio 与使用其他 UNIX 实用工具相比更具有优势,包括:
cpio 可以备份和恢复单独的文件而不只是所有文件系统。
cpio 在文件上创建的文件头信息较小,导致备份量较少。
tar 被限制在单台磁带设备上,cpio 则不同,它可以跨越多个磁带。
cpio 运行在三种模式中: copy-out ( cpio -o)、 copy-in ( cpio -i)和 pass 模式 ( cpio -p),最后一种模式用于从磁盘上(而不是磁带)的一个位置复制文件到另一个位置。下节列出了几个常用的选项。

cpio 命令选项
除非另行指出,否则这些选项适用于 copy-out 和 copy-in 模式。

-c: 以 ASCII 格式写入头信息, 为了便于移植。
-d: 创建所需的目录。
-v: Verbose (处理时报告文件名)。
-V: 与前面相同, 除了为每个复制的文件显示一个 “.”。
-u: 用于无条件复制;旧文件将不会替换较新的文件。
-m: 保留以前的文件修改时间。该选项在复制目录时不起作用。

要将一个目录及其子目录复制到磁带上,使用下面的例子:
% ls -R | cpio -oVc >; /dev/rmt/0
上面的例子将把当前所在的目录以及其中的所有子目录复制到位于 /dev/rmt/0 的磁带设备。-o 指定处于 copy-out 模式。-V 选项代表 verbose 并将显示.作为进度指示符。-c 选项创建一个 ASCII 头文件。

要将内容从磁带复制回目录,使用下面的例子:
% cpio -icvD < /dev/rmt/0

在上面的例子中,我们的命令将使用多个选项恢复磁带上的数据内容。-i 选项使工作处于 copy-in 模式。-d 选项在将数据复制回来的时候创建所有所需的目录。

利用 cpio 备份文件(Copy-Out 模式)
利用 cpio 有多种方法来备份文件,我在这里将介绍其中的两种。

% cpio -ov list >; /dev/rmt/0
这个命令从文件“list”读取内容并将其复制到磁带设备。

% cpio -o /dev/rmt/0
这个命令允许您指定要备份的文件。输入文件名后,按 Ctrl+D 键执行该命令。下面是一个例子:
% cpio -o >; /dev/rmt/0
filename.txt
file1name.txt

利用 cpio 恢复文件(Copy-In 模式)
利用 cpio 的恢复过程与备份文件的过程类似。只是不使用 -o 指定 copy-out 模式,我们使用 -i 模式将数据从磁带复制回来。

% cpio -icvum < /dev/rmt/0
这个例子利用了与先前使用的类似选项,还有 -m 选项,它将保留文件的修改时间。

使用下面的例子查看磁带存档上的内容列表:
% cpio -ict < /dev/rmt/0

Pass 模式
Pass 模式可用于在磁盘设备上复制目录。它在磁带上将无法工作。当要复制文件和目录时,,cpio 要优于 cp,因为它保留了文件的所有权和修改时间。

下面的例子将所有文件和目录复制到一个称为 bkup 的目录中:

% ls * | cpio -pdumv bkup

pax — 可移植存档互换(提取、写入和列出存档文件)
pax 实用工具可以在很多与 POSIX 兼容的 UNIX 系统上找到。Solaris 操作系统从版本 2.5 开始就包含它了。pax 具有读写 tar 和 cpio 存档的能力。根据您选择如何使用 pax,它将运行于 4 种模式之一:读、写、列表和复制。要设置模式,您可以使用 -r、-w 、这两者的组合或者根本不用选项。

pax 模式选项
选项 模式 描述
-r 读 单个 -r 选项只是读模式,这允许您从磁盘或磁带读文件
无 列表 如果 -r 或 -w 选项都没有, pax 将被置于列表模式。它将从磁盘、磁带或标准输入设备读文件并且显示文件和目录层次结构
-w 写 单个 -w 选项让 pax 处于写模式。 它将依照 -x 选项指定的格式将当前目录和其中的所有子目录复制到独立的输出设备。(参见下面的例子)。如果没有指定文件,可以从标准的输入设备上读入一个列表,一次一个文件
-rw 复制 同时指定 -r 和 -w 选项,所选择的文件被复制到目的目录

pax 命令选项
选项 描述
-a 将文件附加到先前写入的存档的末尾
-b 块大小。 块大小最低为 512 字节, 或者以 512 为增量的更大块,最大 32256 字节
-c 匹配所有文件或存档成员,除了那些用 Pattern 和文件操作数指定的
-f <archive>; 指定 <archive>; 作为输入或输出存档的路径名。一个存档可以跨越多台设备。pax 提示您在存档中的下一设备的路径名
-i 交互地重命名文件或存档成员。 用于通过标准输入为可选择性的写或复制提供文件名
-p <string>; 指定在提取或存档一个文件时所用的一个或多个文件特征选项a 不保留文件访问时间
e 保留一切:用户 ID、组ID、文件模式位、文件访问时间和修改时间。
m 不保留文件修改时间
o 保留用户 ID 和组 ID
P 保留文件模式位
v Verbose 模式

-x 指定输出存档格式。默认格式是 ustar。 pax 可以支持 cpio、 tar、 bcpio、 ustar、 sv4crc 和 sv4cpio
ufsdump命令

对系统管理员而言,ufsdump命令很有用,可对整个文件系统做完全或增量转储.
完全转储是对整个文件系统做备份.在较长的间隔做一次,如一星期或一月.
增量转储是对新创建或修改的文件进行备份.增量转储更频繁一些,可能一天一次.

ufsdump命令提供了不同等级的转储,从0至9.转储等级用来确定对哪些文件备份.0级指定完全转储,1至9指定不同等级的增量转储.例如,增量转储(1等级)将对在上一次低等级 (0级)转储后修改或创建的文件进行备份.对文件系统作备份时,应将系统转至运行等级S.

如系统在运行等级3时,文件可能正在使用,于是可能造成无效备份.

例子:

# ufsdump 0uf /dev/rmt/0 /export/home

选项及参数:
0
指定0级(完全)转储.

u
更新文件/etc/dumpdates,以记录成功的转储.

f
与下面的/dev/rmt/0参数一起确定转储的磁带设备.
/dev/rmt/0
转储的磁带设备.
/export/home
指定要转储的文件系统.

ufsrestore命令
ufsrestore命令从备份磁带上拷贝文件至当前目录下.
ufsrestore命令可用于重载转储好的整个文件系统或备份带上的单个或多个文件.
ufsrestore命令的选项用来指定磁带设备名和被恢复文件的路径名.

恢复过程
用ufsrestore命令按以下步骤恢复一个文件:
# cd /newdir
# ufsrestore tuf /dev/rmt/0

gzip 命令

语法:gzip [选项] 压缩(解压缩)的文件名该命令的各选项含义如下:

-c 将输出写到标准输出上,并保留原有文件。-d 将压缩文件解压。-l 对每个压缩文件,显示下列字段:     压缩文件的大小;未压缩文件的大小;压缩比;未压缩文件的名字-r 递归式地查找指定目录并压缩其中的所有文件或者是解压缩。-t 测试,检查压缩文件是否完整。-v 对每一个压缩和解压的文件,显示文件名和压缩比。-num 用指定的数字 num 调整压缩的速度,-1 或 –fast 表示最快压缩方法(低压缩比),-9 或–best表示最慢压缩方法(高压缩比)。系统缺省值为 6。e.g.

gzip *% 把当前目录下的每个文件压缩成 .gz 文件。gzip -dv *% 把当前目录下每个压缩的文件解压,并列出详细的信息。gzip -l *% 详细显示例1中每个压缩的文件的信息,并不解压。gzip usr.tar% 压缩tar备份文件 usr.tar,此时压缩文件的扩展名为.tar.gz。Solaris下的tar没有和gzip结合起来,不像Linux的tar有z命令。如果希望tar的同时也能压缩或者解压可以这样写:打包压缩tar cvf – testfile | gzip > testfile.tar.gz解包gunzip -c testfile.tar.gz | tar xvf

本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/uper945/archive/2008/02/29/2133148.aspx

从源文件安装软件

在班图中附带了丰富的软件,这些软件一般使用图形化的自动方式即可轻松安装,但是对于那些刚刚问世的新软件,班图还未收录其中,这时我们就需要用到一种更通用的安装方式:通过手工方式从源文件来安装这些软件。下面就介绍这种手工安装方式的详细步骤。

一、 安装编译程序

因为要编译源代码,所以第一步就是安装编译和构建之类的程序。在班图系统中非常简单,只要执行下面命令就行了:

$ sudo apt-get install build-essential

该命令执行后,从源文件安装软件所需的工具,如gcc、make、g++及其他所需软件就安装好了。

二、下载并编译软件的源代码

当我们下载源文件时,一定要弄清该软件所依赖的库文件和其他程序,并且首先将它们装好。这些信息,通常都能在该开源项目的主页上查找到。做好这些准备工作后,我们就可以进行下面的工作了。因为,软件的源代码通常以压缩文件形式发布,所以需要将其解压到指定目录。命令如下所示:

baby@ubuntu:~$ tar xvzf program.tar.gz

baby@ubuntu:~$ cd program/

在Linux下从源文件安装程序时,有一个通用模式,即配置–编译–安装。但是,此前你最好还是阅读源文件中附带的安装说明,因为对于每个程序,其开发者的指示才是最具权威性的。程序开发者通常将安装说明存放在名为INSTALL 或README。到哪里找这些文件呢?它们在项目主页或源代码主目录中都能找到。

1.配置

构建应用的第一步就是执行configure脚本,该脚本位于程序源文件的主目录下:

baby@ubuntu:~/program$ ./configure

该脚本将扫描系统,以确保程序所需的所有库文件业已存在,并做好文件路径及其他所需的设置工作。如果程序所需的库文件不完全,该配置脚本就会退出,并告诉您还需要哪些库文件或者是哪些版本太旧需要更新。如果遇到这种情况,仅弄到含有该库文件的软件包还是不够的,同时还要找到具有该库文件所有头文件的开发包,在班图中,这样的包一般以-dev作为文件名的结尾。安装好所有需要的库文件后,重新运行配置脚本,直到没有错误提示为止,这说明需要的库文件已经全部安装妥当了。

2.编译

当配置脚本成功退出后,接下来要做的就是编译代码了。具体操作为在源文件的主目录中运行make命令:

baby@ubuntu:~/program$ make

这时,您会看到一串编译输出数据迅速从屏幕上滚过,如果正常的话,系统会返回的提示符状态。然而,如果编译过程中出现错误的话,排错的过程可就不像配置步骤那么简单了。因为,这通常要涉及到源代码的调试,可能源代码有语法错误,或其他错误等等。怎么办?如果您是编程高手,那就自己调试吧!否则,检查该软件的邮件列表等支持渠道,看看是不是已知的bug,如果是就看看别人是怎么解决的,不是就提交一份bug报告吧,也许不久就会有解决办法。

3.安装

当软件成功编译后,最后一步就是将它们安装到系统上。大部分程序的makefile文件中都会有一个用于安装

的函数。需要注意的是,大多时候我们必须作为root用户来安装程序,这样程序就把文件安装到/usr或其他

只有超级用户才有写权限的目录中。依旧是在源文件的主目录下,执行如下命令:

baby@ubuntu:~/program$ sudo make install

好了,这样程序就会安装到您的计算机上了。另外,当您不再使用该程序时,可以使用软件所带的卸载功能,一般程序都会具备此功能。切换至源文件的主目录下,执行以下命令即可:

baby@ubuntu:~/program$ sudo make uninstall

多数情况下,利用上面介绍的方法安装的程序,都位于/usr/local下面。若想让安装的程序文件与班图巡视的文件系统隔离开的话,可以为命令添加项,如下所示:

baby@ubuntu:~/program$ ./configure –prefix=/opt

尽管这样做一般都是有效的,但是也有例外,有些程序根本不理会项;有些程序如含有内核模块的程序,会把它们自己全部放进您的文件系统。

三、小结

上面介绍的手工安装软件的方法虽然是针对班图环境来介绍的,但是各种Linux系统下的从源文件安装应用的

方法基本上都大同小异。只要读者举一反三,触类旁通,在其他系统下遇到从源文件安装软件的情况时,就不会无从下手了。

Ubuntu下开机进程管理工具sysv-rc-conf

一、sysv-rc-conf简介
       sysv-rc-conf是一个强大的服务管理程序,群众的意见是sysv-rc-conf比chkconfig好用。
二、背景知识
1、Ubuntu运行级别
Linux 系统任何时候都运行在一个指定的运行级上,并且不同的运行级的程序和服务都不同,所要完成的工作和要达到的目的都不同,系统可以在这些运行级之间进行切换,以完成不同的工作。

Ubuntu 的系统运行级别:

0
        系统停机状态
1
        单用户或系统维护状态
2~5
    多用户状态
6
        重新启动

查看当前运行级别,执行命令:
runlevel
( runlevel 显示上次的运行级别和当前的运行级别,“N”表示没有上次的运行级别。)

切换运行级别,执行命令:    
int [0123456Ss]
( 即在 init 命令后跟一个参数,此参数是要切换到的运行级的运行级代号,如:用 init 0 命令关机;用 init 6 命令重新启动。)

Linux 系统主要启动步骤:
    1. 读取 MBR 的信息,启动 Boot Manager
            Windows 使用 NTLDR 作为 Boot Manager,如果您的系统中安装多个
            版本的 Windows,您就需要在 NTLDR 中选择您要进入的系统。
            Linux 通常使用功能强大,配置灵活的 GRUB 作为 Boot Manager。
    2. 加载系统内核,启动 init 进程
            init 进程是 Linux 的根进程,所有的系统进程都是它的子进程。
    3. init 进程读取 /etc/inittab 文件中的信息,并进入预设的运行级别,
       按顺序运行该运行级别对应文件夹下的脚本。脚本通常以 start 参数启
       动,并指向一个系统中的程序。
            通常情况下, /etc/rcS.d/ 目录下的启动脚本首先被执行,然后是
            /etc/rcN.d/ 目录。例如您设定的运行级别为 3,那么它对应的启动
            目录为 /etc/rc3.d/ 。
    4. 根据 /etc/rcS.d/ 文件夹中对应的脚本启动 Xwindow 服务器 xorg
            Xwindow 为 Linux 下的图形用户界面系统。
    5. 启动登录管理器,等待用户登录
            Ubuntu 系统默认使用 GDM 作为登录管理器,您在登录管理器界面中
            输入用户名和密码后,便可以登录系统。(您可以在 /etc/rc3.d/
            文件夹中找到一个名为 S13gdm 的链接)

三、安装sysv-rc-conf
sudo apt-get install sysv-rc-conf

四、使用sysv-rc-conf
sudo sysv-rc-conf
操作界面十分简洁,你可以用鼠标点击,也可以用键盘方向键定位,用空格键选择,用
Ctrl+N翻下一页,用Ctrl+P翻上一页,用Q退出。

常见的系统服务有:
acpi-support 高级电源管理支持
acpid acpi 守护程序.这两个用于电源管理,非常重要
alsa 声音子系统
alsa-utils
anacron cron 的子系统,将系统关闭期间的计划任务,在下一次系统运行时执行。
apmd acpi 的扩展
atd 类似于 cron 的任务调度系统。建议关闭
binfmt-support 核心支持其他二进制的文件格式。建议开启
bluez-utiles 蓝牙设备支持
bootlogd 启动日志。开启它
cron 任务调度系统,建议开启
cupsys 打印机子系统。
dbus 消息总线系统(message bus system)。非常重要
dns-clean 使用拨号连接时,清除 dns 信息。
evms 企业卷管理系统(Enterprise Volumn Management system)
fetchmail 邮件用户代理守护进程,用于收取邮件
gdm gnome 登录和桌面管理器。
gdomap
gpm 终端中的鼠标支持。
halt 别动它。
hdparm 调整硬盘的脚本,配置文件为 /etc/hdparm.conf。
hibernate 系统休眠
hotkey-setup 笔记本功能键支持。支持类型包括: HP, Acer, ASUS, Sony,Dell, 和 IBM。
hotplug and hotplug-net 即插即用支持,比较复杂,建议不要动它。
hplip HP 打印机和图形子系统
ifrename 网络接口重命名脚本。如果您有十块网卡,您应该开启它
inetd 在文件 /etc/inetd.conf 中,注释掉所有你不需要的服务。如果该文件不包含任何服务,那关闭它是很安全的。
klogd 重要。
linux-restricted-modules-common 受限模块支持。
/lib/linux-restricted-modules/ 文件夹中的模块为受限模块。例如某些驱动程序,如果您没有使用受限模块,就不需要开启它。
lvm 逻辑卷管理系统支持。
makedev 创建设备文件,非常重要。
mdamd 磁盘阵列
module-init-tools 从/etc/modules 加载扩展模块,建议开启。
networking 网络支持。按 /etc/network/interfaces 文件预设激活网络,非常重要。
ntpdate 时间同步服务,建议关闭。
pcmcia pcmcia 设备支持。
powernowd 移动 CPU 节能支持
ppp and ppp-dns 拨号连接
readahead 预加载库文件。
reboot 别动它。
resolvconf 自动配置 DNS
rmnologin 清除 nologin
rsync rsync 守护程序
sendsigs 在重启和关机期间发送信号
single 激活单用户模式
ssh ssh 守护程序。建议开启
stop-bootlogd 在 2,3,4,5 运行级别中停止 bootlogd 服务
sudo 检查 sudo 状态。重要
sysklogd 系统日志
udev & udev-mab 用户空间 dev 文件系统(userspace dev filesystem)。重要
umountfs 卸载文件系统
urandom 随机数生成器
usplash 开机画面支持
vbesave 显卡 BIOS 配置工具。保存显卡的状态
xorg-common 设置 X 服务 ICE socket。
adjtimex 调整核心时钟的工具
dirmngr 证书列表管理工具,和 gnupg 一起工作。
hwtools irqs 优化工具
libpam-devperm 系统崩溃之后,用于修理设备文件许可的守护程序。
lm-sensors 板载传感器支持
mdadm-raid 磁盘陈列管理器
screen-cleanup 清除开机屏幕的脚本
xinetd 管理其他守护进程的一个 inetd 超级守护程序

vi命令

一、基本命令介绍
—- 1.光标命令
k、j、h、l——上、下、左、右光标移动命令。虽然您可以在Linux中使用键盘右边的4个光标键,但是记住这4个命令还是非常有用的。这4个键正是右手在键盘上放置的基本位置。
nG——跳转命令。n为行数,该命令立即使光标跳到指定行。
Ctrl+G——光标所在位置的行数和列数报告。
w、b——使光标向前或向后跳过一个单词。
—- 2.编辑命令
i、a、r——在光标的前、后以及所在处插入字符命令(i=insert、a=append、r=replace)。
cw、dw——改变(置换)/删除光标所在处的单词的命令 (c=change、d=delete)。
x、d$、dd——删除一个字符、删除光标所在处到行尾的所有字符以及删除整行的命令。
—- 3.查找命令
—- /string、?string——从光标所在处向后或向前查找相应的字符串的命令。
—- 4.拷贝复制命令
—- yy、p——拷贝一行到剪贴板或取出剪贴板中内容的命令。
二、常见问题及应用技巧
—- 1.在一个新文件中读/etc/passwd中的内容,取出用户名部分。
—- vi file
—- :r /etc/passwd 在打开的文件file中光标所在处读入/etc/passwd
—- :%s/:.*//g 删除/etc/passwd中用户名后面的从冒号开始直到行尾的所有部分。
—- 您也可以在指定的行号后读入文件内容,例如使用命令“:3r /etc/passwd”从新文件的第3行开始读入 /etc/passwd的所有内容。
—- 我们还可以使用以下方法删掉文件中所有的空行及以#开始的注释行。
—- #cat squid.conf.default | grep -v ^$ | grep -v ^#
—- 2.在打开一个文件编辑后才知道登录的用户对该文件没有写的权限,不能存盘,需要将所做修改存入临时文件。
—- vi file
—- :w /tmp/1 保存所做的所有修改,也可以将其中的某一部分修改保存到临时文件,例如仅仅把第20~59行之间的内容存盘成文件/tmp/1,我们可以键入如下命令。
—- vi file
—- :20,59w /tmp/1
—- 3.用VI编辑一个文件,但需要删除大段的内容。
—- 首先利用编辑命令“vi file”打开文件,然后将光标移到需要删除的行处按Ctrl+G显示行号,再到结尾处再按Ctrl+G,显示文件结尾的行号。
—- :23,1045d 假定2次得到的行号为23和1045,则把这期间的内容全删除,也可以在要删除的开始行和结束行中用ma、mb命令标记,然后利用“:a,bd”命令删除。
—- 4.在整个文件的各行或某几行的行首或行尾加一些字符串。
—- vi file
—- :3,$s/^/some string / 在文件的第一行至最后一行的行首插入“some string”。
—- :%s/$/some string/g 在整个文件每一行的行尾添加“some string”。
—- :%s/string1/string2/g 在整个文件中替换“string1”成“string2”。
—- :3,7s/string1/string2/ 仅替换文件中的第3行到第7行中的“string1”成“string2”。
—- 注意: 其中s为substitute,%表示所有行,g表示global。
—- 5.同时编辑2个文件,拷贝一个文件中的文本并粘贴到另一个文件中。
—- vi file1 file2
—- yy 在文件1的光标处拷贝所在行
—- :n 切换到文件2 (n=next)
—- p 在文件2的光标所在处粘贴所拷贝的行
—- :n 切换回文件1
—- 6.替换文件中的路径。
—- 使用命令“:%s#/usr/bin#/bin#g”可以把文件中所有路径/usr/bin换成/bin。也可以使用命令“:%s//usr/bin//bin/g”实现,其中“”是转义字符,表明其后的“/”字符是具有实际意义的字符,不是分隔符。
linux下Vi编辑器命令大全
输入”/”,回车
里面有很多文件夹,如:etc,home,lib,mnt等等
etc:存放用户名和密码
home:每个用户有个文件夹,存放在这里
lib:操作系统文件等
mnt:挂扣用的
opt:java工具
bea:web编程的一些东西
sbin,bin,usr:这三个文件夹都是存放unix的命令的
tmp:临时文件夹
常用的操作:
查看当前目录:pwd
修改密码:passwd
更换模式:csh,bash
远程登陆:telnet 服务器ip
回到上级目录:cd ..
查看该目录下的文件夹:ls
打开文件:vi /文件夹/文件
文件显示的格式:root:x:0:root…:/root;/bin/bash 用户名,加密,序号,组,默认路径
退出:esc shift+: q! quit exit
清空:clear
显示当前目录所有文件:ls –a
显示当前目录所有文件和详细信息:ls –al
新建文件:vi 文件名
文件的权限:chmod g –(+)r w x u g o s
新建文件(不能编辑)更新文件的访问时间,如果存在文件,更新,不存在,建立:touch 文件名
创建目录:mkdir 目录名/目录名
创建多个目录:mkdir 目录名 目录名…..
在主目录创建下目录:mkdir ~/目录名
创建多级目录:mkdir –p 目录名/目录名
在覆盖文件前做个提示:cp –I
文件和文件内容间的拷贝:cp
复制目录:cp –r 目录 目录
复制文件:cp 文件 文件
移动文件:mv 要移动的文件 要移动到的目录
移动目录:mv -fi要移动的目录 要移动到的目录
修改文件或目录的名字:mv 文件 名字
删除文件:rm rm –I提示
删除目录中的所有内容包括目录:rm –r 要删除的文件夹
连接:软连接:相当于创建快捷方式,作用:修改linux内核会用到他 in
硬连接:如果删除源文件,被连接的文件内容还存在
帮助:man 命令
补全名字:table
显示日历:cal
输入:>
输出:<
查看文件内容:cat 例子:cat文件
分屏显示:ls –l/目录|more
合并到一个新的文件:cat a.txt b.txt
设置环境变量:
csh中 .cshrc source cshrc
bash中 .profile 执行..profile或者source .profile
本编辑器是所有计算机系统中最常用的一种工具。UNIX下的编辑器有ex,sed和vi等,其中,使用最为广泛的是vi,而vi命令繁多,论坛里好像这方面的总结不多,以下稍做总结,以资共享!渴望更正和补充!
进入vi的命令
vi filename :打开或新建文件,并将光标置于第一行首
vi +n filename :打开文件,并将光标置于第n行首
vi + filename :打开文件,并将光标置于最后一行首
vi +/pattern filename:打开文件,并将光标置于第一个与pattern匹配的串处
vi -r filename :在上次正用vi编辑时发生系统崩溃,恢复filename
vi filename….filename :打开多个文件,依次进行编辑
移动光标类命令
h :光标左移一个字符
l :光标右移一个字符
space:光标右移一个字符
Backspace:光标左移一个字符
k或Ctrl+p:光标上移一行
j或Ctrl+n :光标下移一行
Enter :光标下移一行
w或W :光标右移一个字至字首
b或B :光标左移一个字至字首
e或E :光标右移一个字至字尾
) :光标移至句尾
( :光标移至句首
}:光标移至段落开头
{:光标移至段落结尾
nG:光标移至第n行首
n+:光标下移n行
n-:光标上移n行
n$:光标移至第n行尾
H :光标移至屏幕顶行
M :光标移至屏幕中间行
L :光标移至屏幕最后行
0:(注意是数字零)光标移至当前行首
$:光标移至当前行尾
屏幕翻滚类命令
Ctrl+u:向文件首翻半屏
Ctrl+d:向文件尾翻半屏
Ctrl+f:向文件尾翻一屏
Ctrl+b;向文件首翻一屏
nz:将第n行滚至屏幕顶部,不指定n时将当前行滚至屏幕顶部。
插入文本类命令
i :在光标前
I :在当前行首
a:光标后
A:在当前行尾
o:在当前行之下新开一行
O:在当前行之上新开一行
r:替换当前字符
R:替换当前字符及其后的字符,直至按ESC键
s:从当前光标位置处开始,以输入的文本替代指定数目的字符
S:删除指定数目的行,并以所输入文本代替之
ncw或nCW:修改指定数目的字
nCC:修改指定数目的行
删除命令
ndw或ndW:删除光标处开始及其后的n-1个字
do:删至行首
d$:删至行尾
ndd:删除当前行及其后n-1行
x或X:删除一个字符,x删除光标后的,而X删除光标前的
Ctrl+u:删除输入方式下所输入的文本
搜索及替换命令
/pattern:从光标开始处向文件尾搜索pattern
?pattern:从光标开始处向文件首搜索pattern
n:在同一方向重复上一次搜索命令
N:在反方向上重复上一次搜索命令
:s/p1/p2/g:将当前行中所有p1均用p2替代
:n1,n2s/p1/p2/g:将第n1至n2行中所有p1均用p2替代
:g/p1/s//p2/g:将文件中所有p1均用p2替换
选项设置
all:列出所有选项设置情况
term:设置终端类型
ignorance:在搜索中忽略大小写
list:显示制表位(Ctrl+I)和行尾标志($)
number:显示行号
report:显示由面向行的命令修改过的数目
terse:显示简短的警告信息
warn:在转到别的文件时若没保存当前文件则显示NO write信息
nomagic:允许在搜索模式中,使用前面不带“\”的特殊字符
nowrapscan:禁止vi在搜索到达文件两端时,又从另一端开始
mesg:允许vi显示其他用户用write写到自己终端上的信息
最后行方式命令
:n1,n2 co n3:将n1行到n2行之间的内容拷贝到第n3行下
:n1,n2 m n3:将n1行到n2行之间的内容移至到第n3行下
:n1,n2 d :将n1行到n2行之间的内容删除
:w :保存当前文件
:e filename:打开文件filename进行编辑
:x:保存当前文件并退出
:q:退出vi
:q!:不保存文件并退出vi
:!command:执行shell命令command
:n1,n2 w!command:将文件中n1行至n2行的内容作为command的输入并执行之,若不指定n1,n2,则表示将整个文件内容作为command的输入
:r!command:将命令command的输出结果放到当前行
寄存器操作
"?nyy:将当前行及其下n行的内容保存到寄存器?中,其中?为一个字母,n为一个数字
"?nyw:将当前行及其下n个字保存到寄存器?中,其中?为一个字母,n为一个数字
"?nyl:将当前行及其下n个字符保存到寄存器?中,其中?为一个字母,n为一个数字
"?p:取出寄存器?中的内容并将其放到光标位置处。这里?可以是一个字母,也可以是一个数字
ndd:将当前行及其下共n行文本删除,并将所删内容放到1号删除寄存器中。