繁体   English   中英

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

[英]What does the following assembly does for the following .c file

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

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

void main()
{
    printf("%d", ((hh*)0)+1);
}  

部件:

        .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"

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

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

        .section        ".rodata"
        .align 8
.LLC0:
        .asciz  "%d\n"

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

        .section        ".text"
        .align 4
        .global main
        .type   main, #function
        .proc   020
main:

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

        save    %sp, -112, %sp

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

        sethi   %hi(.LLC0), %g1
        or      %g1, %lo(.LLC0), %o0

这个双指令序列的作用是将地址.LLC0 (这是你的字符串常量)加载到寄存器%o0 ,这是第一个输出参数寄存器。 函数的参数是在进入的参数寄存器。)

        mov     100, %o1

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

        call    printf, 0
        nop

打电话给printf nop填入延迟槽(再次阅读架构手册)。 我不记得零是什么。

        return  %i7+8
        nop

跳转到寄存器%i7的地址加上8。 这具有从当前函数返回的效果。 在延迟槽中应该有一个restore指令,我不知道它为什么不存在。

程序集调用printf ,传递文本缓冲区和堆栈上的数字20(这是你以迂回方式要求的)。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM