读CSAPP之公理和抽象

Computer System: A Programmer’s Perspective

中国语言文化很深奥,同样的话,不同人说,不同场合说,表达的意思就千差完毕。所以,要揣摩说话者的心思,就得把他的话放到具体的语境里,稍不留神就会弄出岔子。

通常,人们认为计算机没有二义性,一是一,二十二。实际上,在计算机中,所有的信息表示方式都是一致的,存在着同样一段表示形式对应的信息是不唯一的。

只有在指明了特定的解读方式以后,这些表现形式才能表示唯一的信息,我把它定义为计算机系统第一公理:

  1. 信息由一串位表示,只有在特定的上下文中,其才具有意义。

计算机系统是硬件和系统软件的结合体,硬件构成了物理存在,见上图。而系统软件更多指的是操作系统,其具备两个基本功能:

    [ Read More » ]

读《Professional Assembly Language》之插入排序

Professional Assembly Language

《Professional Assembly Language》看完了第一、二部分,回顾这段时间的学习,收获似乎并没有想象中那么大,觉得掌握的还是皮毛。期间,搭配阅读《Computer System: A Programmer’s Perspective》、《The C Programming Language》,对计算机的理解和对程序的掌控能力只是有提升,而谈不上跃升。我想,最主要的原因还是缺少动手去写代码。

插入排序常常是书本当中用来引导读者进入算法领域的hello, world,这次我尝试用汇编代码来实现它。在这之前,首先把C语言实现版本张贴如下,以便参考:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
void insertion_sort(int array[], int length)
{
    int j;
    for (j = 1; j < length; j++)
    {
        int i = j - 1;
        int key = *(array + j);
        while (i >= 0 && *(array + i) > key)
        {
            *(array + i + 1) = *(array + i);
            i--;
        }
        *(array + i + 1) = key;
    }
 
}
[ Read More » ]

读《Professional Assembly Language》之栈随机化

Professional Assembly Language

本书的第十一章是讲解函数的使用,特别是C风格的函数调用,也就是栈(Stack)在函数调用中的用场。在章节的末尾,讲到了命令行参数,其中涵盖了Linux是如何安排程序的内存空间的。

正如文中所言,每个程序可使用的内存空间起止地址均相同,–当然,这只是Linux玩弄的一个小把戏:虚拟地址空间。

The virtual memory address assigned to the program running in Linux starts at address 0x8048000 and end at address 0xbffffff.

上面这段话,把起止地址说明白了,如图1所示,大致分为两块,低位的块是保存代码和数据,高位的块是程序栈,ESP寄存器保存栈顶地址。

[ Read More » ]

读《Professional Assembly Language》之系统调用

Professional Assembly Language

《Professional Assmebly Language》的第十二章是《Using Linux System Call》,这一章围绕系统调用展开,并对比了C库函数调用。在过往的经历中,我对函数调用的认识全都止于C库函数,这次终于有了对系统调用的初步认识,于是从一开始便对int $0x80的疑惑,在这一章有了一个清晰的答案。

Linux系统调用(system call)的过程是这样的:

  • 首先,将要调用的system call number放入到eax寄存器中;
  • 然后,将参数按照要求依次放入ebx、ecx等寄存器中;
  • 接着,调用int $0x80;
  • 最后,从eax寄存器中获取返回值。

整个过程比较简单,–除了获取返回值时可能会遇到复杂的数据结构。

[ Read More » ]

Android Application Framework Outside, Service Understanding : 4

Android

在上文当中提到的service命令,它是如何获得服务的信息呢?这个这个仅为275行的简单程序(framework/base/cmds/service/service.cpp)并未有什么特别神奇的地方,从本质上它对服务信息一无所知,所有的信息都是通过IPC获得。

IPC(Inter Process Communication)几乎总是伴随着Service出现,–不论是系统服务,还是应用服务,因为服务运行的进程大部分和应用运行的进程不同。

Android有意淡化IPC,甚至使其透明,就连Android Dev Guide也只是对IPC只做简明的解释说明,Android这样做的目的是降低应用开发的技术门槛,使开发者更多关注业务逻辑等商业价值点。

注意:RPC的全称为Remote Procedure Call,虽然和IPC只有一字之差,但并不相同。

IPC只是一种概念,实现IPC的方式有多种,例如在linux上你可以使用socket等,而Android中则采用了Binder。

[ Read More » ]