操作系统之汇编语言(1)

简单的汇编语言
下面,让我们先来看一段简单的代码:

int accum=0;
int sum(int x, int y){
    int t=x+y;
    accum+=t;
    return t;
}

我们在命令行上执行下面指令:

gcc -01 -S code.c

这会使GCC 运行编译器,产生一个汇编文件code.c。汇编语言是一种更接近计算机底层的机器级语言:

sum:
   push1 %ebp
   movl %esp,%ebp
   movl 12(%ebp),%eax
   addl 8(%ebp), %eax
   addl %eax,accum
   popl %ebp
   ret  

如果我们使用’-c’命令行选项,GCC会编译并汇编该代码:

gcc -01 -c code.c

这就会产生目标代码文件code.c,它是二进制格式文件,所以无法直接查看。

数据格式
在Intel的体系里面,它用字(word)表示16位的数据结构,因此,称32位数为双子,称64位数为四字,我们的对数指令都是对字节或双字操作的。在32位的操作系统中,所有的指针都是(用char*表示)都存储为4字节的双字,所有sizeof(pointer)的大小为4字节,而在64位系统中,sizeof(pointer)的大小为8字节。所以32位地址的系统可以寻址4GB的地址范围,而64位地址系统可以寻址8GB的地址范围,但是通常一个程序只会访问几兆字节。
数据传送指令有三个变种:movb(传送字节),movw(传送字)和movl(传送双子)。

访问信息
一个32位的中央处理器单元(CPU)包含一组8个32位值的寄存器,这些寄存器用来存储整数数据和指针,下图显示了这8个寄存器,每个名字都以%e开头:

这里写图片描述
这些寄存器的操作数指示符有一个或者多个操作数,指示出执行一个操作中要引用的源数据值,以及放置结果的目标位置。源数据值可以以常数的形式读出,或是从寄存器或存储器读出。结果可以存放在寄存器或者存储器中。我们可以把操作室指示符分为三类:
1.立即数
立即数的书写方式$后面跟一个用标准C表示法表示的整数,如$0x108表示的值为0x108
2.寄存器
它表示某个寄存器的内容,对双字操作来说,可以是8个32位寄存器中的一个(例如,%eax),对字操作来说,可以是8个16位寄存器中的一个(例如:%ax),如操作数%eax的值可能为0x100,操作数%edx的值可能为0x3。
3.存储器的引用
它会根据计算出来的地址(通常称为有效地址)访问某个存储器的位置,因为将存储器看成一个很大的字节数组。地址0x10C的值为0x11,所以操作数9(%eax,%edx)的值为0x11,0x11=0x100+0x03+0x09

push1和pop1**数据传送操作**可以将数据压入程序栈中,以及从程序栈中弹出数据。栈是一种数据结构,可以添加或者删除值,是遵循“后进先出”的原则。程序栈存放在存储器中某个区域,栈顶是向下生长的,所以栈顶元素的只是所有栈中元素地址中最低的。栈指针%esp保存着栈顶元素的地址。

这里写图片描述

将一个双字值压入栈中,首先要将栈指针减4,然后将值写入新的栈顶地址。因此push1 %ebp的行为等价于一下两条指令:

sub1 %4%ebp
movl %ebp,(%esp)

它们之间的区别在于目标代码中push1指令编码为一个字节,而上面两条指令一共需要6个字节。从图中我们可以看到,无论是push1还是pop1操作,%esp指向的位置总是栈顶,任何存储在栈顶之外的数据都认为是无效的。
下面我们来看看一个数据传送的示例:

int exchange(int *xp,int y){
    int x=*xp;
    *xp=y;
    return x;
}

下面代码是是上面示例的汇编代码:

//xp at %epb+8,y at %ebp+12
1 movl 8(%ebp),%edx
2 movl (%edx), %eax
3 movl  12(%ebp), %ecx
4 movl  %eax, (%edx) 

当过程体开始执行时,过程参数xp和y存储在相对寄存器%ebp中地址值(注意,是寄存器中的地址值)偏移8和12的地方。指令1从存储器当中读出参数xp,把它放到寄存器%edx中。指令3将参数y加载到寄存器%ecx,然后指令4将这个值写到寄存器%edx中的xp指向的存储器的位置,直接实现了操作*xp=y。

在这段代码中有两个地方是值得注意的,首先,我们看到c语言中的所谓指针,其实就是指地址。间接引用指针就是将该指针放在一个寄存器中,而不是存储器中。其次,像x这样的局部变量通常保存在寄存器中,而不是存储器中。寄存器访问比存储器访问要快得多。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值