诗意代码 – PoemCode

These codes, As beautiful as poetry!

assembly

  • 读《Professional Assembly Language》之插入排序

    Professional Assembly Language

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

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

    void insertion_sort(int array[], int length)
    {
        int j;
        for (j = 1; j = 0 && *(array + i) > key)
            {
                *(array + i + 1) = *(array + i);
                i--;
            }
            *(array + i + 1) = key;
        }
        
    }
    

    阅读全文 →

  • 读《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寄存器保存栈顶地址。

    阅读全文 →

  • 读《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寄存器中获取返回值。

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

    阅读全文 →

  • 读《Professional Assembly Language》之移位之谜

    Professional Assembly Language

    《Professional Assembly Language》在第八章第二节讲解了Shift Instruction,在谈到算数左移(SAL)和逻辑左移(SHL)时,作者列举了该指令的三种格式:

    1. sal destination
    2. sal %cl, destination
    3. sal shifter, destination

    其中,第三种格式表述存不清楚,shifter可以是immediate value?是common register?是memory location?下面先用shifter是memory location类型来做个试验。

    .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
    

    阅读全文 →

  • 读《Professional Assembly Language》之奇怪的if-then-else

    Professional Assembly Language

    在本书英文版第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
    

    create the following assembly language code:

    if:
        cmpl %eax, %ebx
        jle else
        cmpl %eax, %ecx
        jne else
    then:
        
        jmp end
    else:
          
    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.

    阅读全文 →