可能重复:
使用GCC生成可读组件?
例如,当我尝试:
gcc -c myprogram
它会给我一个目标文件,它是二进制形式.我想得到的只是一个汇编文件(在由汇编程序处理以生成目标文件之前).有没有办法在gcc中做到这一点?
例如,我定义了一个宏:
#ifdef VERSION
//.... do something
#endif
Run Code Online (Sandbox Code Playgroud)
如何检查VERSION目标文件中是否存在?我试着用它拆解它objdump,但发现我的宏没有实际价值VERSION.VERSION在Makefile中定义.
问题是:对于在较大项目中其他地方使用foo.c的.c文件,是否应将foo.oMakefile列表中的目标文件编译目标foo.h作为依赖项?
foo.o: foo.c foo.h
$(CC) $(CFLAGS) -c -o foo.o foo.c
Run Code Online (Sandbox Code Playgroud)
这只是一个常规问题吗?
这是我到现在为止的想法,并且回答了一个问题:
似乎任何合法的改变foo.h都需要相应的改变foo.c.因此,没有必要foo.h列为依赖项.但是,这可能是一个好主意,因为我们希望立即通知(通过重新编译)如果更改foo.h破坏了任何内容foo.c.
我有两个文件,print_permu.c和gen_permu.cpp.我希望将print_permu.c文件编译成目标文件,然后使用目标文件进行编译gen_permu.cpp,其中包含对函数的调用print_permu.c.
print_permu.c
#include<stdlib.h>
#include<stdio.h>
typedef char byte;
char *printable=NULL;
size_t pos,size,*char_cnt;
void __print_permu_recurse()
{
if( pos==size )
{
printf("%s\n",printable);
return;
}
byte iter = 25;
while( iter>=0 )
{
if( char_cnt[iter] )
{
printable[pos] = 'a'+iter;
--char_cnt[iter];
++pos;
__print_permu_recurse();
--pos;
++char_cnt[iter];
}
--iter;
}
}
void print_permu(size_t *char_count)
{
char_cnt = char_count;
for(pos = 0,size = 0 ; pos<26 ; ++pos)
size += char_count[pos];
printable = (char*)malloc(sizeof(char)*(size+1));
printable[size] = '\0'; …Run Code Online (Sandbox Code Playgroud) 我希望了解程序集级别的printf()语句.但是,大多数汇编程序执行的操作类似于调用外部打印函数,其依赖性由链接器添加的其他目标文件满足.我想知道在打印函数内部的系统调用和非常基本的汇编代码.我想要一个汇编代码,其中唯一的外部调用是系统调用,对于printf.我在考虑类似于已组装的目标文件.我在哪里能得到类似的东西?
正如标题所示:为什么编译器仅从 .cpp 文件而不是头文件生成目标文件 .o ?如果实现位于 .h 文件中,链接器如何知道如何将目标文件链接在一起?
根据此ELF 规范:ELF 目标文件包含各种部分,其中之一是符号表部分 .symtab,其中包含所有符号(文件、函数、对象等)的信息。
ELF 包含符号表中每个符号的名称、属性标志、类型、值和绑定等信息。
文件、函数或对象(数组、变量、字符串)等的对象名称实际上暴露了代码的内部信息。这样,任何人都可以分析ELF(使用strings,objdump或readelf工具),看到此信息,并获得对事物的内部,其应当保密的代码的想法。
为了可读性和可维护性,我们编写了开发人员可以理解的代码。所以,我们需要继续使用正确的文件名和变量名等。我们不能使用代码混淆来掩盖它们,因为它会导致难以维护。
问题(已编辑):有什么方法可以在可执行 ELF 的符号表中隐藏或删除符号“名称”,以便没有人可以了解代码并且可执行文件仍然可以运行?
我正在尝试将程序集文件编译为目标文件。该汇编文件调用 ac 函数。但我遇到这个错误:二进制输出格式不支持外部引用
我在汇编文件第17行调用c函数
我尝试用这个命令编译它:
cpu/interrupt.o: cpu/interrupt.asm
nasm $< -f bin -o $@
Run Code Online (Sandbox Code Playgroud)
我该如何解决这个问题
[extern isr_handler]
; Common ISR code
isr_common_stub:
; 1. Save CPU state
pusha ; Pushes edi,esi,ebp,esp,ebx,edx,ecx,eax
mov ax, ds ; Lower 16-bits of eax = ds.
push eax ; save the data segment descriptor
mov ax, 0x10 ; kernel data segment descriptor
mov ds, ax
mov es, ax
mov fs, ax
mov gs, ax
; 2. Call C handler
call isr_handler
; 3. Restore state
pop …Run Code Online (Sandbox Code Playgroud) 为什么编译的编程语言(例如C++)被设置为创建许多链接在一起的目标文件而不是正在创建的一个大对象?
例如(用C++编写,能适用于任何编译语言),考虑在项目中的两个文件main.cpp和auxiliary.cpp.是什么区别main.cpp和auxiliary.cpp被编译main.o并auxiliary.o再联系到main.exe,并main.cpp用#include auxiliary.cpp被编译成只main.o与挂钩main.exe?据我所知,这些至少会表面上产生相同的结果.
在多语言项目的情况下,我看到了多个对象的必要性,但不是这样.多个对象是否以某种方式使链接器在创建可执行文件时更具灵活性?
在我的 FASM 项目(对象)中,我尝试创建一个跳转表并用于dq每个跳转地址,但有一个问题!
对于每个dq .jmp1(跳转地址定义),.jmp1我的最终 .o 文件的总大小将添加 24 个字节(加上地址的 8 个字节(总共 32 个字节))!
那额外的 24 个字节是什么?有什么办法可以避免吗?这种情况仅发生在目标文件中,而不发生在可执行文件中!
它定义了 32 个字节,而不是每个跳转地址 8 个字节!问题是什么?
format ELF64
section '.text'
func:
lea rax, [8*rax+.jmp_table]
.jmp1:
.jmp_table:
dq .jmp1 ; 8 bytes + 24 bytes !!! (to .o total size)
dq .jmp1 ; 8 bytes + 24 bytes !!! (to .o total size)
Run Code Online (Sandbox Code Playgroud)
但是当我创建一个可执行文件时,每个文件dq只需要 8 个字节(这是我所期望的)......
format ELF64 EXECUTABLE
segment readable executable
func:
lea rax, [8*rax+.jmp_table]
.jmp1:
.jmp_table: …Run Code Online (Sandbox Code Playgroud) object-files ×10
c ×5
assembly ×3
c++ ×2
linker ×2
compilation ×1
dependencies ×1
elf ×1
executable ×1
fasm ×1
g++ ×1
gcc ×1
header ×1
header-files ×1
makefile ×1
nasm ×1
symbol-table ×1
system-calls ×1
unix ×1
x86 ×1
x86-64 ×1