kk Blog —— 通用基础

date [-d @int|str] [+%s|"+%F %T"]

FTP命令

  • ftp 很快就会自动断开,lftp命令一样,更好用

Linux 终端连接FTP

1
2
3
4
5
6
7
$ ftp 10.85.7.97

Name (10.85.7.97:oracle): super

Password:   -- Linux 的密码是不回显的

ftp>

如果FTP 允许匿名用户,那么用户名要输入anonymous,密码任意。 不能直接敲回车。

查看FTP 命令

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
ftp> ?
Commands may be abbreviated.  Commands are:
!               cr              mdir            proxy           send
$               delete          mget            sendport        site
account         debug           mkdir           put             size
append          dir             mls             pwd             status
ascii           disconnect      mode            quit            struct
bell            form            modtime         quote           system
binary          get             mput            recv            sunique
bye             glob            newer           reget           tenex
case            hash            nmap            rstatus         trace
ccc             help            nlist           rhelp           type
cd              idle            ntrans          rename          user
cdup            image           open            reset           umask
chmod           lcd             passive         restart         verbose
clear           ls              private         rmdir           ?
close           macdef          prompt          runique
cprotect        mdelete         protect         safe

可以通过help command 查看每个命令的说明

1
2
3
4
ftp> help put
put             send one file
ftp> help mput
mput            send multiple files

上传文件

Put命令:格式:put local-file [remote-file] 将一个文件上传到ftp
Mput命令:格式:mput local-files 将本地主机中一批文件传送至远端主机.
注意:mput命令只能将当前本地目录下的文件上传到FTP上的当前目录。比如,在/root/dave下运行的ftp命令,则只有在/root/dave下的文件linux才会上传到服务器上的当前目录下。

Put 代码示例:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
ftp> pwd    -- 显示FTP上当前路径
257 "/" is current directory.
ftp> ls   -- 显示当前目录下的文件

ftp> mkdir Dave    -- 创建文件夹Dave

ftp> cd Dave      -- 进入文件夹Dave

ftp> pwd        -- 显示当前目录

ftp> lcd     -- 显示当前本地的路径,我们可以将这个路径下的这个文件上传到FTP服务器的相关位置

ftp> !      -- 退出当前的窗口,返回Linux 终端,当我们退出终端的时候,又会返回到FTP上。
$ ls  -- 显示当前目录下的文件

$ vi Dave  -- 创建文件Dave
$ vi DBA   -- 创建文件DBA
$ ls       -- 显示文件夹里的内容,等会我们将这些文件copy到FTP上

$ exit  -- 退出终端,返回FTP命令行
exit
ftp> lcd

ftp> put DBA DBA    -- 将刚才创建的文件DBA 上传到ftp的当前目录上并命名为DBA。

ftp> put DBA /Dave/SFDBA -- 将刚才创建的文件DBA 上传到ftp的当前目录上并重命名为SFDBA。

ftp> put /home/oracle/DBA /test/SFDBA  

ftp> cd test

ftp> ls
Mput 示例代码:
1
2
3
4
5
6
7
8
9
10
11
ftp>cd Dave

ftp>mput *
mput alert_log.txt?    -- 这里每个文件都要确认,按回车键就可以了

ftp> ls       -- 显示目录下的文件

ftp> delete SFDBA   --删除SFDBA 文件

ftp> mdelete a*   -- 批量删除文件
mdelete alert_log.txt?  -- 每个文件都要确认

下载文件

同样也有2个命令:get 和mget。Mget 用户批量下载。
格式:get [remote-file] [local-file]
mget [remote-files]
同样,mget 是将文件下载到本地的当前目录下。

Get 示例:
1
2
3
4
5
6
7
8
9
ftp> get /test/SFDBA /home/SFDBA

local: /home/SFDBA: Permission denied  --Linux对权限控制的很严格,下载的时候是否有对应文件夹的写权限
ftp>  get /test/SFDBA /home/oracle/SFDBA

ftp> !
$ cd /home/oracle/
$ls
Dave  DBA  dead.letter  scripts  SFDBA  sqlnet.log
Mget 示例:
1
2
3
4
5
6
7
ftp> ls

ftp> mget *
mget DBA?  -- 每个文件都要确认, 按回车即可

ftp> !
$ ls

说明的地方:FTP 当前目录下的文件下载到本地的当前目录。

断开FTP 连接

Bye命令或者quit命令:中断与服务器的连接。

1
2
ftp> bye
221 Goodbye!

js滚动标题

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>滚动标题</title>
<script language="javascript">
var title_string = "让你的标题栏文字动起来,标题也动了";
var title_length = title_string.length;
var index_count = 0;
var cmon;

function scrollTheTitle()
{
    var doc_title = title_string.substring(index_count, title_length);
    document.title = doc_title;
    index_count++;
}

function loopTheScroll()
{
    scrollTheTitle();
    if(index_count >= title_length)
    {
	index_count = 0;
	//clearTimeout(cmon);
    }
    cmon = setTimeout("loopTheScroll();",300)
}
loopTheScroll();
//-->
</script>
</head>
</html>

gcc include

本文介绍在linux中头文件的搜索路径,也就是说你通过include指定的头文件,linux下的gcc编译器它是怎么找到它的呢。在此之前,先了解一个基本概念。

头文件是一种文本文件,使用文本编辑器将代码编写好之后,以扩展名.h保存就行了。头文件中一般放一些重复使用的代码,例如函数声明、变量声明、常数定 义、宏的定义等等。当使用#include语句将头文件引用时,相当于将头文件中所有内容,复制到#include处。#include有两种写法形式, 分别是:

1
2
#include <> : 直接到系统指定的某些目录中去找某些头文件。
#include “” : 先到源文件所在文件夹去找,然后再到系统指定的某些目录中去找某些头文件。

#include文件可能会带来一个问题就是重复应用,如a.h引用的一个函数是某种实现,而b.h引用的这个函数却是另外一种实现,这样在编译的时候将会出现错误。所以,为了避免因为重复引用而导致的编译错误,头文件常具有:

1
2
3
4
#ifndef    LABEL
#define    LABEL
	//代码部分
#endif

的格式。其中LABEL为一个唯一的标号,命名规则跟变量的命名规则一样。

gcc寻找头文件的路径(按照1->2->3的顺序)

1.

在gcc编译源文件的时候,通过参数-I指定头文件的搜索路径,如果指定路径有多个路径时,则按照指定路径的顺序搜索头文件。命令形式如:“gcc -I /path/where/theheadfile/in sourcefile.c“,这里源文件的路径可以是绝对路径,也可以是相对路径。eg:
设当前路径为/root/test,include_test.c如果要包含头文件“include/include_test.h“,有两种方法:
1) include_test.c中#include “include/include_test.h”或者#include “/root/test/include/include_test.h",然后gcc include_test.c即可
2) include_test.c中#include <include_test.h>或者#include <include_test.h>,然后gcc –I include include_test.c也可

2.

通过查找gcc的环境变量C_INCLUDE_PATH/CPLUS_INCLUDE_PATH/OBJC_INCLUDE_PATH来搜索头文件位置。

3. 再找内定目录搜索,分别是
1
2
3
/usr/include
/usr/local/include
/usr/lib/gcc-lib/i386-linux/2.95.2/include

最后一行是gcc程序的库文件地址,各个用户的系统上可能不一样。
gcc在默认情况下,都会指定到/usr/include文件夹寻找头文件。

gcc还有一个参数:-nostdinc,它使编译器不再系统缺省的头文件目录里面找头文件,一般和-I联合使用,明确限定头文件的位置。在编译驱动模块时,由于非凡的需求必须强制GCC不搜索系统默认路径,也就是不搜索/usr/include要用参数-nostdinc,还要自己用-I参数来指定内核 头文件路径,这个时候必须在Makefile中指定。

4.

当#include使用相对路径的时候,gcc最终会根据上面这些路径,来最终构建出头文件的位置。如#include <sys/types.h>就是包含文件/usr/include/sys/types.h

常用汇编指令对标志位的影响

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
加法指令 ADD (addition)
指令对标志位的影响:
                     CF=1   最高有效位向高位有进位
                     CF=0   最高有效位向高位无进位
                     OF=1   两个同符号数相加(正数+正数 或 负数+负数),结果符号与其相反。
                     OF=0   两个不同符号数相加,或同符号数相加,结果符号与其相同。

带进位加法指令 ADC (add with carry)
指令对标志位的影响:
                     CF=1   最高有效位向高位有进位
                     CF=0   最低有效位相高位无进位
                     OF=1   两个同符号数相加,结果符号与其相反,
                     OF=0   两个同符号数相加,或同符号相加,结果符号与其相同

加1指令 INC (increament)
指令对标志位的影响:
                     对CF无影响
                     OF=1   两个同符号数相加,结果符号与其相反,
                     OF=0   两个同符号数相加,或同符号相加,结果符号与其相同。
 
减法指令 SUB (subtract)
指令对标志位的影响:
                     CF=1 二进制减法运算中最高有效位向高位有借位(被减数小于减数,不够减的情况)
                     CF=0 二进制减法运算中最高有效为向高位无借位(被减数〉=减数,够减的情况)
                     OF=1 两数符号相反(正数-负数,或负数-正数),而结果符号与减数相同。
                     OF=0 同符号数相减时,或不同符号数相减,其结果符号与减数不同。

带借位减法指令 SBB (subtract with borrow)
指令对标志位的影响:
                     CF=1 二进制减法运算中最高有效位向高位有借位(被减数小于减数,不够减的情况)
                     CF=0 二进制减法运算中最高有效为向高位无借位(被减数〉=减数,够减的情况)
                     OF=1 两数符号相反(正数-负数,或负数-正数),而结果符号与减数相同。
                     OF=0 同符号数相减时,或不同符号数相减,其结果符号与减数不同。

减1指令 DEC (decrement)
指令对标志位的影响:
                     对CF无影响
                     OF=1 两数符号相反(正数-负数,或负数-正数),而结果符号与减数相同。
                     OF=0 同符号数相减时,或不同符号数相减,其结果符号与减数不同。
                    
比较指令 CMP (compare)
指令对标志位的影响:
                     CF=1 二进制减法运算中最高有效位向高位有借位(被减数小于减数,不够减的情况)
                     CF=0 二进制减法运算中最高有效为向高位无借位(被减数〉=减数,够减的情况)
                     OF=1 两数符号相反(正数-负数,或负数-正数),而结果符号与减数相同。
                     OF=0 同符号数相减时,或不同符号数相减,其结果符号与减数不同。

求补指令 NEG (negate)
指令对标志位的影响:
                     CF=1  不为0的操作数求补时
                     CF=0  为0的操作数求补时
                     OF=1    操作数为-128(字节运算)或操作数为-32768(字运算)
                     OF=0    当求补运算的操作数不为-128(字节)或-32768(字)时

无符号乘法指令 MUL (unsigned multiple)    有符号乘法指令 IMUL(signed muliple)
指令对标志位的影响:乘法指令只影响标志位CF和OF,其他条件码位无定义。
                     MUL指令的条件码设置为:
                     CF OF=0 0 乘积的高一半为0(字节操作的(AH)或字操作的(DX))
                     CF OF=1 1 乘积的高一半不为0
                     IMUL指令的条件码设置为:
                     CF OF=0 0 乘积的高一半为低一半的符号扩展.
                     CF OF=1 1 其他情况

无符号数除法 DIV (unsigned divide)     带符号数除法 IDIV (singed divide)
指令对标志位的影响:不影响条件码。

逻辑与 AND (logic and)
指令对标志位的影响:
                     指令执行后 CF 和 OF 置零,AF无定义。
                     PF=1 结果操作数中1的个数为偶数时置1
                     PF=0 结果操作数中1的个数为奇数时置0

逻辑或 or (logic or)
指令对标志位的影响:
                     令执行后 CF 和 OF 置零,AF无定义。
                     PF=1 结果操作数中1的个数为偶数时置1
                     PF=0 结果操作数中1的个数为奇数时置0

逻辑非 NOT (logic not)
指令对标志位的影响:对标志位无影响

异或 XOR (exclusice or)
指令对标志位的影响:
                     令执行后 CF 和 OF 置零,AF无定义。
                     PF=1 结果操作数中1的个数为偶数时置1
                     PF=0 结果操作数中1的个数为奇数时置0

测试指令 TEST
指令对标志位的影响:
                     令执行后 CF 和 OF 置零,AF无定义。
                     PF=1 结果操作数中1的个数为偶数时置1
                     PF=0 结果操作数中1的个数为奇数时置0

逻辑左移 SHL (shift logical left)
指令对标志位的影响:CF=移入的数值
                     OF=1 当cnt=1时,移动后最高位的值发生变化。
                     OF=0 当cnt=1时,移动时最高位的值未发生变化。

逻辑右移 SHR (shift logical right)
指令对标志位的影响:CF=移入的数值
                     OF=1 当cnt=1时,移动后最高位的值发生变化。
                     OF=0 当cnt=1时,移动时最高位的值未发生变化。

算术左移 SAL (shift arithmetic left)
指令对标志位的影响:CF=移入的数值
                     OF=1 当cnt=1时,移动后最高位的值发生变化。
                     OF=0 当cnt=1时,移动时最高位的值未发生变化。

算术右移 SAR (shift arithmetic right)
指令对标志位的影响:CF=移入的数值
                     OF=1 当cnt=1时,移动后最高位的值发生变化。
                     OF=0 当cnt=1时,移动时最高位的值未发生变化。

循环左移 ROL (rotate left)
指令对标志位的影响:CF=移入的数值
                     OF=1 当cnt=1时,移动后最高位的值发生变化。
                     OF=0 当cnt=1时,移动时最高位的值未发生变化。

循环右移 ROR (rotate right)
指令对标志位的影响:CF=移入的数值
                     OF=1 当cnt=1时,移动后最高位的值发生变化。
                     OF=0 当cnt=1时,移动时最高位的值未发生变化。

带进位的循环左移 RCL (rotate left through carry)
指令对标志位的影响:CF=移入的数值。
                     OF=1 当cnt=1时,移动后最高位的值未发生变化。
                     OF=0 当cnt=1时,移动后最高位的值发生变化。
                     SF、ZF、PF标志位不受影响。

带进位的循环右移 RCR (rotate right through carry)
指令对标志位的影响:CF=移入的数值。
                     OF=1 当cnt=1时,操作数最高位的值未发生变化。
                     OF=0 当cnt=1时,操作数最高位的值发生变化。
                     SF、ZF、PF标志位不受影响。

串传送 MOVSB / MOVSW (move string byte/word)
指令对条件码的影响:不影响条件码。

存串 STOSB / STOSW (stroe from string byte/word)
指令对条件码的影响:不影响条件码。

取串LODSB / LODSW (load from string byte/word)
指令对条件码的影响:不影响条件码。

串比较 CMPSB / CMPSW (compare string byte/word)
指令对条件码的影响:
                     CF=1 二进制减法运算中最高有效位向高位有借位(被减数小于减数,不够减的情况)
                     CF=0 二进制减法运算中最高有效为向高位无借位(被减数〉=减数,够减的情况)
                     OF=1 两数符号相反(正数-负数,或负数-正数),而结果符号与减数相同。
                     OF=0 同符号数相减时,或不同符号数相减,其结果符号与减数不同。

串扫描 SCASB / SCASW (scan string byte / word)
指令对条件码的影响:
                     CF=1 二进制减法运算中最高有效位向高位有借位(被减数小于减数,不够减的情况)
                     CF=0 二进制减法运算中最高有效为向高位无借位(被减数〉=减数,够减的情况)
                     OF=1 两数符号相反(正数-负数,或负数-正数),而结果符号与减数相同。
                     OF=0 同符号数相减时,或不同符号数相减,其结果符号与减数不同。

条件转移指令
指令的汇编格式及功能    根据条件码的值转移:
49、JZ(JE) OPR        ZF=1
50、JNZ(JNE) OPR   ZF=0
51、JS OPR             SF=1
52、JNS OPR           SF=0
53、JO OPR             OF=1
54、JNO OPR          OF=0
55、JP OPR             PF=1
56、JNP OPR           PF=0
57、JC OPR             CF=1
58、JNC OPR          CF=0

比较两个无符号数,根据比较的结果转移
59、JB(JNAE,JC)   OPR   CF=1         被减数小于减数则转移
60、JNB(JAE,JNC) OPR   CF=0         被减数大于或等于减数则转移
61、JBE(JNA) OPR      CF或ZF=1      被减数小于或等于减数则转移
62、JNBE(JA) OPR      CF或ZF=0      被减数大于减数则转移

比较两个带符号数,根据比较结果转移
63、JL/JNGE OPR       SF异或OF=1           被减数小于减数则转移
64、JNL/JGE           SF异或OF=0               被减数不小于减数则转移
65、JLE/JNE           (SF异或OF)与ZF=1     被减数不大于减数则转移
66、JNLE/JG           (SF异或OF)与ZF=0     被减数大于减数则转移

根据CX寄存器的值转移
67、JCXZ              (CX)=0               CX内容为零 则转移

c与汇编的关系

_start是汇编程序的入口,main是c程序的入口?
gcc 只是一个 外壳而不是真正的编译器,这真的c编译器是/usr/lib/gcc/i486-gun/4.3.2/cc1,gcc调用c编译器、汇编器和链接器完成c 代码的编译链接工作。/usr/lib/gcc/i486-linux-gun/4.3.2/collect2是链接器ld的外壳,它调用ld完成链接。

i main.c被cc1编译成汇编程序/tmp/ccRGDpua.s。
ii 这个汇编程序被as汇编成目标文件/tmp/ccidnZ1d.o
iii 这个目标文件连同另外几个目标文件(crt1.o,crti.o,crtbegin.o,crtend.o,crtn.o)一起链接成可执行文件 main。在链接过程中还用-l,选项指定一些库文件,有libc、libgcc、ligcc_s,其中有些库是共享库,需要动态链接,所以用 -dynamic-linker选项指定动态链接器是/lib/ld-linux.so.2

1
2
3
4
5
6
7
8
9
10
$ nm /usr/lib/crt1.o
00000000 R  _IO_stdin_used
00000000 D __data_start
                 U __libc_csu_fini
                 U __libc_csu_init
                 U __libc_start_main
00000000 R _fp_hw
00000000 T _start
00000000 W data_start
                 U main

U main 这一行表示main这个符号在crt1.o已经被引用了,但是还没有定义(Undefined),因此需要别的目标文件提供一个定义并且和crt1.o链接在一起。T_start表示在crt1.o中已定义为(text)。

c 程序的入口点其实是crt1.o提供的start,它先做一些初始化工作(启动例程,startup routine),然后调用我们编写的main函数。所以,main函数是程序的入口,不够准确。start才是真正的入口点,而main函数是被 _start调用的。

U __libc_start_main,这个符号在其他几个目标文件中也没有定义,所以链接生成可执行文件之后仍然是个未定义符号。事实上这个符号在 libc中定义,libc是一个共享库,它并不像其他目标文件一样链接到可执行文件main中,而是在运行时做动态链接:
i 操作系统在加载main这个程序时,首先看它有没有需要动态链接的未定义符号。
ii如果需要做动态链接,就查看这个程序指定了哪些共享库,以及用什么动态链接器来做动态链接。我们在链接时用-lc选项指定了共享库libc,用-dynamic-linker /lib/ld-linux.so.2 指定动态链接器,这些信息都会写到可执行文件中。
iii动态连接器加载共享库,在其中查找这些未定义符号的定义,完成链接过程。

c内联汇编

完整的内联汇编格式:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
__asm__(asembler template
		:output operands
		: input operands
		: list of clobbered registers
		);

e.g.

#include <stdio.h>
int main(void)
{
	int a=10,b;
	__asm__("movl %1,%%eax\n\t"
			"movl %%eax,%0\n\t"
			:"=r"(b)  //把%0所代表的寄存器的值输出给变量b
			:"r"(a)       //告诉编译器分配一个寄存器保存变量a的值,作为汇编程序的输入,对应%1
			:"%eax"
	);
	printf("result:%d,%d\n",a,b);
	return 0;
}