在x86_64的环境中,把《程序员的自我修养》第4.6.2节中的例子敲了一遍,始终无法编译通过。
源码
[code]
char* str = "OK!\n";

void print(){
asm("movl $4,%%edx \n\t"
"movl %0,%%ecx \n\t"
"movl $0,%%ebx \n\t"
"movl $4,%%eax \n\t"
"int $0x80 \n\t"
::"r"(str):"edx","rcx","ebx"
);
}

void exit(){
asm("movl $42,%ebx \n\t"
"movl $1,%eax \n\t"
"int $0x80 \n\t");
}

void nomain(){
print();
exit();
}
[/code]
编译的错误提示
[code]
tok.c: Assembler messages:
tok.c:5: Error: suffix or operands invalid for `mov'
[/code]

- 阅读剩余部分 -

一、进程虚拟地址空间
1、程序和进程的区别:程序是可执行文件,程序运行的过程,通过一个或多个进程来完成。程序是静态的物理文件,进程是运行时的过程。
2、虚拟地址空间(Virtual Address Space):由硬件平台的CPU位数决定。大小为2的cpu位数次方减去1。
3、Linux进程虚拟空间分布:操作系统(OS)高位1G,用户进程低位3G。
4、PAE(Physical Address Extension)物理地址扩展。物理地址由32位扩展到36位。类似于之前把16位的地址线扩展到20位。
5、AWE(Address Windowing Extensions)窗式地址扩展。有点像扇区的访问方式。
二、装载的方式
1)、覆盖装入。程序员自己写覆盖管理器,用于合理分配和释放内存。生成依赖树,不能跨树调用。
2)、页映射。虚拟存储机制的一部分,按各种淘汰算法换出内存,缺页时加载。
三、从操作系统角度看可执行文件的装载。
1)、进程的建立。创建VAS,与可执行文件映射,启动。
2)、页错误。缺页加载。

- 阅读剩余部分 -

一、Windows的二进制文件格式 PE/COFF
1、PE(Protable Executable):可在各版本的Windows平台上运行。实际上只支持x86的CPU。
2、PE/COFF:VC++编译的目标代码还是COFF格式,可执行文件是PE格式。
3、PE32+:只是把原先32位的字段变成了64位。
4、也是段的结构,段名只有提示作用,没有实际意义。
二、PE的前身--COFF
1、COFF跟ELF非常像,可以找到跟ELF的文件结构相对应的地方。映像头、段表、各段。
2、映像(Image):在装载时被映射到进程的虚拟空间,所以也被叫做映像文件(Image File)。
三、链接指示信息
1、.drectve(Directive)段,编译器希望告诉链接器该怎样链接这个目标文件。
四、调试信息
1、.debug开始的段,都包含调试信息。
2、.debug$S代表符号相关的调试信息段。.debug$P代表预编译头文件相关的调试信息段。.debug$T表示类型相关的调试信息。
五、大家都有符号表。
1、最后部分是COFF的符号表。
六、Windows下的ELF--PE
PE与COFF的区别:
0.1 开始部分不是COFF文件头,是DOS MZ可执行文件格式的文件头和桩代码。兼容DOS而做。
0.2 原COFF文件头中的IMAGE_FILE_HEADER作为PE文件头IMAGE_NT_HEADERS的一部分。
0.3 PE兼容MZ格式,扩展名相同,在DOS下运行仅输出提示信息。
1)、PE数据目录。用于保存装载所需要的数据结构(导入表、导出表、资源、重定位表)的位置和长度。

1、相对地址修正为S + A - P,晕了很长时间。简单总结一下
S没问题,很确定是要调用方法的实际地址。绝对地址。
A没问题,链接之前放的值,也就是常量-4。
P被修正的位置,容易晕。实际上是call指令所在的地址加一,也就是call后的值的地址。
而且,使用常量-4的原因是call指令用的地址是32位的(也就是4个字节)

2、编译器将未初始化的全局变量当作弱符号来处理,所以不在BSS段分配空间。
第三章小结的时候,发现了这个问题,在这一章已经描述了,只在链接时才会分配到bss段。
http://msblog.tk/archives/430

3、最小程序的问题。已经另有一遍blog描述了。
http://msblog.tk/archives/424

GPS在刚开始定位成功时,偏差很大,过一段时间,会慢慢较准。我一直的理解是刚开始参与定位的卫星少,后来多了以后才更精准的。

偶然发现有别的因素。

1、先列官方最简单直接的说明,Selective Availability,摘录如下:http://www.gps.gov/systems/gps/modernization/sa/

Selective Availability

chart GPS accuracy errors before and after deactivation of SA (VIEW MORE DATA)
Selective Availability (SA) was an intentional degradation of public GPS signals implemented for national security reasons.

In May 2000, at the direction of President Bill Clinton, the U.S government discontinued its use of Selective Availability in order to make GPS more responsive to civil and commercial users worldwide.

The United States has no intent to ever use Selective Availability again.
In September 2007, the U.S. government announced its decision to procure the future generation of GPS satellites, known as GPS III, without the SA feature. Doing this will make the policy decision of 2000 permanent and eliminate a source of uncertainty in GPS performance that had been of concern to civil GPS users worldwide.

- 阅读剩余部分 -

1、有一处错误。59页第三行:
[code]
所以.bss段只是为未初始化的全局变量和局部静态变量预留位置而已。
[/code]
并且配了图,全局的未初始化变量int global_uninit_var;用点虚线连到.bss section

实测结果发现是错的。
只有静态的未初始化变量会预留位置。非静态的全局变量不会预留。

测试代码bss.c
[code]
int a;
int main(){
return 0;
}
[/code]
头信息显示,.bss的Size为0
[code]
bss.o: file format elf64-x86-64

Sections:
Idx Name Size VMA LMA File off Algn
0 .text 0000000b 0000000000000000 0000000000000000 00000040 2**2
CONTENTS, ALLOC, LOAD, READONLY, CODE
1 .data 00000000 0000000000000000 0000000000000000 0000004c 2**2
CONTENTS, ALLOC, LOAD, DATA
2 .bss 00000000 0000000000000000 0000000000000000 0000004c 2**2
ALLOC
3 .comment 0000002d 0000000000000000 0000000000000000 0000004c 2**0
CONTENTS, READONLY
4 .note.GNU-stack 00000000 0000000000000000 0000000000000000 00000079 2**0
CONTENTS, READONLY
5 .eh_frame 00000038 0000000000000000 0000000000000000 00000080 2**3
CONTENTS, ALLOC, LOAD, RELOC, READONLY, DATA
[/code]

把全局变量改为全局静态变量时,才会到.bss段
[code]
static int a;
int main(){
return 0;
}
[/code]

头信息显示,.bss的Size为4,一个int的大小,四个字节。
[code]
bss.o: file format elf64-x86-64

Sections:
Idx Name Size VMA LMA File off Algn
0 .text 0000000b 0000000000000000 0000000000000000 00000040 2**2
CONTENTS, ALLOC, LOAD, READONLY, CODE
1 .data 00000000 0000000000000000 0000000000000000 0000004c 2**2
CONTENTS, ALLOC, LOAD, DATA
2 .bss 00000004 0000000000000000 0000000000000000 0000004c 2**2
ALLOC
3 .comment 0000002d 0000000000000000 0000000000000000 0000004c 2**0
CONTENTS, READONLY
4 .note.GNU-stack 00000000 0000000000000000 0000000000000000 00000079 2**0
CONTENTS, READONLY
5 .eh_frame 00000038 0000000000000000 0000000000000000 00000080 2**3
CONTENTS, ALLOC, LOAD, RELOC, READONLY, DATA
[/code]
从书中给的例子也能看出来这个问题,61页的代码里分别有一个未初始化的全局变量和一个未初始化的静态局部变量。按作者的理解,这两个int的大小应该是8。
从62页书中给出的头信息来看,.bss段的大小是4。作者不知道什么原因,没有注意到这个问题。

- 阅读剩余部分 -