小编Jee*_*ang的帖子

x86调用约定:堆栈传递的参数应该是只读的吗?

似乎最先进的编译器将堆栈传递的参数视为只读.请注意,在x86调用约定中,调用者将参数压入堆栈,并且被调用者使用堆栈中的参数.例如,以下C代码:

extern int goo(int *x);
int foo(int x, int y) {
  goo(&x);
  return x;
}
Run Code Online (Sandbox Code Playgroud)

clang -O3 -c g.c -S -m32在OS X 10.10中编译成:

    .section    __TEXT,__text,regular,pure_instructions
    .macosx_version_min 10, 10
    .globl  _foo
    .align  4, 0x90
_foo:                                   ## @foo
## BB#0:
    pushl   %ebp
    movl    %esp, %ebp
    subl    $8, %esp
    movl    8(%ebp), %eax
    movl    %eax, -4(%ebp)
    leal    -4(%ebp), %eax
    movl    %eax, (%esp)
    calll   _goo
    movl    -4(%ebp), %eax
    addl    $8, %esp
    popl    %ebp
    retl


.subsections_via_symbols
Run Code Online (Sandbox Code Playgroud)

这里,首先加载参数x(8(%ebp))%eax; 然后存储-4(%ebp) …

c x86 stack calling-convention argument-passing

15
推荐指数
3
解决办法
1486
查看次数

LLVM中的外部注册声明

在Clang或LLVM中,如何正确声明引用CPU寄存器的外部变量?例如,我想表达以下声明(如https://github.com/mit-pdos/xv6-public/blob/master/proc.h#L27):

extern struct cpu *cpu asm("%gs:0");       // &cpus[cpunum()]
extern struct proc *proc asm("%gs:4");     // cpus[cpunum()].proc
Run Code Online (Sandbox Code Playgroud)

看来上面的代码是编译的,但没有以预期的方式链接.我将xv6移植到Rust,作为踏脚石,我将它移植到Clang 3.8.0(而不是GCC).但在构建期间,链接器发出以下错误消息:

ld -m    elf_i386 -T kernel.ld -o kernel entry.o bio.o console.o exec.o file.o fs.o ide.o ioapic.o kalloc.o kbd.o lapic.o log.o main.o mp.o picirq.o pipe.o proc.o sleeplock.o spinlock.o string.o swtch.o syscall.o sysfile.o sysproc.o timer.o trapasm.o trap.o uart.o vectors.o vm.o  -b binary initcode entryother
console.o: In function `panic':
.../console.c:114: undefined reference to `%gs:0'
Run Code Online (Sandbox Code Playgroud)

llvm clang inline-assembly

5
推荐指数
0
解决办法
135
查看次数

clang -O1和opt -O1有什么区别?

clang -O1和之间有什么区别opt -O1?我观察到这两个命令的行为明显不同。

语境

我想测试LLVM优化过程。更具体地说,我想选择一个-O1通行证的子集,以便1)该子集的性能与整体性能相同-O1,以及2)选定的通行证易于推断其正确性。

为了测试子集的性能,我编写了一个shell脚本,例如:

clang -o a.bc -emit-llvm -c a.c
opt (..., optmizations like -adce, ...) a.bc >a.opt.bc
clang -o a a.opt.bc
Run Code Online (Sandbox Code Playgroud)

经过大量尝试,我发现:

clang -o a.bc -emit-llvm -c a.c
opt -O1 a.bc >a.opt.bc
clang -o a a.opt.bc
Run Code Online (Sandbox Code Playgroud)

和clang -O1 -oa ac

发出明显不同的二进制文件。后者要高效得多,例如,对于一个示例程序,前者需要49秒才能运行,而后者则需要29秒。

尝试的方法

  • 我搜索了它的含义clang -O1,并找到了一些参考(例如Clang优化级别),但是这篇文章的确是关于opt,而不是clang

  • 我试图找到的正式文档clang,但没有成果。

  • 我试图了解clang源代码,但我无法...

发现的事实

  • 我尝试过

    clang -o a.bc -emit-llvm -c ac opt -mem2reg -O1 a.bc> …

optimization llvm clang

4
推荐指数
1
解决办法
1565
查看次数