《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;
}
} |
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 » ]
22 9 月, 2011 in
Software | tags:
assembly,
GAS |
No Comments
本书的第十一章是讲解函数的使用,特别是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 Assmebly Language》的第十二章是《Using Linux System Call》,这一章围绕系统调用展开,并对比了C库函数调用。在过往的经历中,我对函数调用的认识全都止于C库函数,这次终于有了对系统调用的初步认识,于是从一开始便对int $0x80的疑惑,在这一章有了一个清晰的答案。
Linux系统调用(system call)的过程是这样的:
- 首先,将要调用的system call number放入到eax寄存器中;
- 然后,将参数按照要求依次放入ebx、ecx等寄存器中;
- 接着,调用int $0x80;
- 最后,从eax寄存器中获取返回值。
整个过程比较简单,–除了获取返回值时可能会遇到复杂的数据结构。
[ Read More » ]
《Professional Assembly Language》在第八章第二节讲解了Shift Instruction,在谈到算数左移(SAL)和逻辑左移(SHL)时,作者列举了该指令的三种格式:
- sal destination
- sal %cl, destination
- sal shifter, destination
其中,第三种格式表述存不清楚,shifter可以是immediate value?是common register?是memory location?下面先用shifter是memory location类型来做个试验。
1
2
3
4
5
6
7
8
9
10
11
12
13
| .section .data
val:
.int 0x1
count:
.int 0x21
.section .text
.global _start
_start:
nop
sall count, val
movl $1, %eax
movl $0, %ebx
int $0x80 |
.section .data
val:
.int 0x1
count:
.int 0x21
.section .text
.global _start
_start:
nop
sall count, val
movl $1, %eax
movl $0, %ebx
int $0x80
[ Read More » ]
13 8 月, 2011 in
Software | tags:
assembly,
GAS |
No Comments
在本书英文版第149、150页(中文版第117页),作者展示了一段稍复杂的C语言if语句,以及对应的汇编伪代码:
Instead of a single conditional jump instruction, there may be several, with each one evaluating a separate part of the if condition. For example, the C language if statment
if (eax < ebx) || (eax == ecx) then |
if (eax < ebx) || (eax == ecx) then
create the following assembly language code:
if:
cmpl %eax, %ebx
jle else
cmpl %eax, %ecx
jne else
then:
< then logic code >
jmp end
else:
< else logic code >
end: |
if:
cmpl %eax, %ebx
jle else
cmpl %eax, %ecx
jne else
then:
< then logic code >
jmp end
else:
< else logic code >
end:
This If statement condition required two separate CMP instructions. Because the logical operator is and OR, if either CMP instruction evaluates to true, the program jumps to the else label.
[ Read More » ]
20 7 月, 2011 in
Software | tags:
assembly,
GAS |
No Comments