Tag: 气体

64位GCC混合32位和64位指针

尽管代码有效,但我对编译器决定混合使用相同类型的32位和64位参数感到困惑。 具体来说,我有一个接收三个char指针的函数。 查看汇编代码,三个中的两个作为64位指针(如预期的那样)传递,而第三个,一个本地常量,但仍然是字符串,作为32位指针传递。 我看不出我的函数在第3个参数不是满载的64位指针时怎么知道。 显然,只要较高的一方为0,它就没关系,但我认为它没有努力确保这一点。 在这个例子中,任何东西都可能在RDX的高端。 我错过了什么? 顺便说一下,接收函数假定它是一个完整的64位指针,并在输入时包含以下代码: movq %rdx, -24(%rbp) 这是有问题的代码: .LC4 .string “My Silly String” .text .globl funky_funk .type funky_funk, @function funky_funk: pushq %rbp movq %rsp, %rbp pushq %rbx subq $16, %rsp movq %rdi, -16(%rbp) ;char *dst 64-bit movl %esi, -20(%rbp) ;int len, 32 bits OK movl $.LC4, %edx ;<<<<—- why is it […]

GCCassembly优化 – 为什么这些相同?

我正在尝试学习assembly如何在初级阶段工作,所以我一直在玩gcc汇编的-S输出。 我写了一个简单的程序,定义了两个字节并返回它们的总和。 整个计划如下: int main(void) { char A = 5; char B = 10; return A + B; } 当我使用以下方法编译时没有优化: gcc -O0 -S -c test.c 我得到test.s,如下所示: .file “test.c” .def ___main; .scl 2; .type 32; .endef .text .globl _main .def _main; .scl 2; .type 32; .endef _main: LFB0: .cfi_startproc pushl %ebp .cfi_def_cfa_offset 8 .cfi_offset 5, -8 […]

了解基指针和堆栈指针:在gcc输出的上下文中

我有以下C程序: int main() { int c[10] = {0, 0, 0, 0, 0, 0, 0, 0, 1, 2}; return c[0]; } 当使用带-gcc的-S指令编译时,我得到以下程序集: .file “array.c” .text .globl main .type main, @function main: .LFB0: .cfi_startproc pushq %rbp .cfi_def_cfa_offset 16 .cfi_offset 6, -16 movq %rsp, %rbp .cfi_def_cfa_register 6 movl $0, -48(%rbp) movl $0, -44(%rbp) movl $0, -40(%rbp) movl $0, […]

GCC不在函数调用中保存/恢复保留寄存器

我在GCC有一个场景给我带来了问题。 我得到的行为不是我期望的行为。 总结一下这种情况,我提出了一些x86-64的新指令,这些指令是在硬件模拟器中实现的。 为了测试这些指令,我使用现有的C源代码并使用hex对新指令进行手动编码。 因为这些指令与现有的x86-64寄存器交互,所以我使用input / output / clobber列表来声明GCC的依赖关系。 发生的事情是,如果我调用一个函数,例如printf,则不会保存和恢复相关寄存器。 例如 register unsigned long r9 asm (“r9”) = 101; printf(“foo %s\n”, “bar”); asm volatile (“.byte 0x00, 0x00, 0x00, 0x00” : /* no output */ : “q” (r9) ); 101被分配给r9,并且内联汇编(在此示例中为假)依赖于r9。 这在没有printf的情况下正确运行,但是当它存在时,GCC不会保存和恢复r9,并且在调用自定义指令时会有另一个值。 我想也许GCC可能秘密地将赋值更改为变量 r9,但是当我这样做时 asm volatile (“.byte %0” : /* no output */ : “q” (r9) ); […]

海湾合作委员会:禁止使用某些登记册

这是一个奇怪的请求,但我有一种感觉,它可能是可能的。 我想要的是将一些pragma或指令插入到我的代码区域(用C语言编写),这样GCC的寄存器分配器就不会使用它们。 我知道我可以做这样的事情,这可能会为这个变量留下这个寄存器 register int var1 asm (“EBX”) = 1984; register int var2 asm (“r9”) = 101; 问题是我直接插入新指令(用于硬件模拟器),而GCC和GAS还没有识别出这些指令。 我的新指令可以使用现有的通用寄存器,我想确保我保留了一些(即r12-> r15)。 现在,我正在模拟环境中工作,我想快速完成我的实验。 将来我会添加GAS并将内在函数添加到GCC中,但是现在我正在寻找快速修复。 谢谢!