以下程序集对以下.c文件执行的操作

Inv*_*tus 4 c compiler-construction assembly sparc

我写了下面的代码,你能解释一下汇编在这里讲的是什么吗?

typedef struct
{
    int abcd[5];
} hh;

void main()
{
    printf("%d", ((hh*)0)+1);
}  
Run Code Online (Sandbox Code Playgroud)

部件:

        .file   "aa.c"
        .section        ".rodata"
        .align 8
.LLC0:

        .asciz  "%d\n"
        .section        ".text"
        .align 4
        .global main
        .type   main, #function
        .proc   020
main:

        save    %sp, -112, %sp
        sethi   %hi(.LLC0), %g1
        or      %g1, %lo(.LLC0), %o0
        mov     20, %o1
        call    printf, 0
         nop
        return  %i7+8
         nop
        .size   main, .-main
        .ident  "GCC: (GNU) 4.2.1"
Run Code Online (Sandbox Code Playgroud)

zwo*_*wol 7

哦,哇,SPARC汇编语言,我多年没见过.

我想我们一行一行?我要跳过一些无趣的样板.

        .section        ".rodata"
        .align 8
.LLC0:
        .asciz  "%d\n"
Run Code Online (Sandbox Code Playgroud)

这是你使用的字符串常量printf(很明显,我知道!)需要注意的重要事项是它在.rodata部分中(部分是最终可执行映像的部分;这部分是"只读数据",并且将在事实上,在运行时是不可变的,并且它已被赋予标签 .LLC0.以点开头的标签对于目标文件是私有的.之后,编译器会在想要加载字符串常量的地址时引用该标签.

        .section        ".text"
        .align 4
        .global main
        .type   main, #function
        .proc   020
main:
Run Code Online (Sandbox Code Playgroud)

.text是实际机器代码的部分.这是用于定义命名的全局函数的样板标题main,它在汇编级别与任何其他函数没有区别(在C中 - 在C++中不一定如此).我不记得是什么.proc 020.

        save    %sp, -112, %sp
Run Code Online (Sandbox Code Playgroud)

保存上一个寄存器窗口并向下调整堆栈指针.如果您不知道注册窗口是什么,则需要阅读体系结构手册:http://www.sparc.org/standards/V8.pdf.(V8是SPARC的最后一个32位迭代,V9是第一个64位迭代.这似乎是32位代码.)

        sethi   %hi(.LLC0), %g1
        or      %g1, %lo(.LLC0), %o0
Run Code Online (Sandbox Code Playgroud)

这个双指令序列具有将地址.LLC0(即你的字符串常量)加载到寄存器的净效果,寄存器%o0是第一个输出参数寄存器.(的参数该功能是在进入的参数寄存器.)

        mov     20, %o1
Run Code Online (Sandbox Code Playgroud)

将立即数100加载到%o1第二个输出参数寄存器中.这是由...计算的值((foo *)0)+1.它是100,因为你的struct foo长度为20个字节(5个4字节ints),你要求在地址0之后的第五个.

        call    printf, 0
        nop
Run Code Online (Sandbox Code Playgroud)

打电话((foo *)0).的((foo *)0)+1延迟槽填充(再次,读取体系结构手册).我不记得零是什么.

        return  %i7+8
        nop
Run Code Online (Sandbox Code Playgroud)

跳转到寄存器中的地址foo加8.这具有从当前函数返回的效果.这里应该printf在延迟槽指令,我不知道为什么它不存在.