首页
学习
活动
专区
工具
TVP
发布
精选内容/技术社群/优惠产品,尽在小程序
立即前往

为什么hello world在C中生成的汇编代码不像x86汇编那样有.code段,也没有模型很小?

在C语言中生成的汇编代码与x86汇编代码的差异主要是由于编译器和目标平台的不同所导致的。下面是对这个问题的详细解答:

在C语言中,编译器将源代码转换为汇编代码,然后再由汇编器将其转换为机器码。汇编代码是一种低级的表示形式,它将C语言的高级语法转换为机器指令的形式。

在x86汇编中,通常会有一个明确的代码段(.code segment),用于存放程序的指令。这是因为x86架构的指令集体系结构规定了代码段的存在。

然而,在C语言中生成的汇编代码中,没有明确的代码段(.code segment)的定义。这是因为C语言的编译器通常会生成与特定平台相关的汇编代码,以便更好地利用该平台的特性和优化编译结果。因此,汇编代码中的指令通常会直接放置在全局数据段(.data segment)或者其他段中。

此外,生成的汇编代码可能会比x86汇编代码更大,这是因为C语言中的一些高级语法和特性需要更多的指令来实现。例如,C语言中的函数调用和参数传递机制可能需要额外的指令来处理。

总结起来,C语言中生成的汇编代码与x86汇编代码的差异主要是由于编译器和目标平台的不同所导致的。C语言的编译器会根据特定平台的特性和优化策略生成相应的汇编代码,而不是遵循固定的代码段结构。

页面内容是否对你有帮助?
有帮助
没帮助

相关·内容

用Rust实现Brainfuck的JIT编译器

x64汇编简介 Linux x64 汇编/Hello World 我们每天产出大量的垃圾代码,我们每个人都可以像这样简单地编写最简单的代码: #include int main()...当然,这将是经典的 Hello World! 程序。这是它的代码: section .data msg db "Hello World!"...首先看第一和第二行,我们定义了数据段部分,并将 msg 常量与 “Hello, World!” 值放在一起。现在,我们可以在代码中使用此常量。接下来是声明文本段部分和程序的入口。...申请一段可写和可执行的内存 将源码翻译为机器码(通常经过汇编) 将机器码写入第一步申请的内存 执行这部分内存 Hello, JIT World: The Joy of Simple JITs 事不宜迟,...而 Rust 生态中也有一个参照 DynASM 所开发的项目,也叫 dynasm: https://crates.io/crates/dynasm 为了在 Rust 中编写汇编代码,我们将使用这个名为

88910

【AI系统】GCC 主要特征

int main(void){ printf(HELLOWORD); return 0;}预处理(cpp)生成文件 hello.i gcc -E hello.c -o hello.i在预处理过程中...world\n".subsections_via_symbols现在 hello.s 文件中包含了完全是汇编指令的内容,表明 hello.c 文件已经被成功编译成了汇编语言。...比如,在 Intel x86 架构或者 Windows 平台下、使用 Visual C++ 编译生成的可执行文件,在同样的 Intel x86 架构/Windows 10 下运行。...比如,在 Intel x86 架构/Linux(Ubuntu)平台下、使用交叉编译工具链生成的可执行文件,在 ARM 架构/Linux 下运行。...其中 GCC 的预处理、编译阶段属于三段式划分的前端部分,汇编阶段属于三段式划分的后端部分。GCC 的链接阶段是三段式划分后端部分的优化阶段合并,但其与端部分的目的一致,都是为了生成可执行文件。

7710
  • 转载:【AI系统】GCC 主要特征

    下面以打印宏定义 HELLOWORD 为例,我们使用 C 语言编写 hello.c 源文件: 代码语言:c复制#include #define HELLOWORD ("hello world...代码语言:c复制int main(void){ printf(("hello world\n")); return 0;}在该文件中,已经将头文件包含进来,宏定义 HELLOWORD 替换为字符串...world\n".subsections_via_symbols现在 hello.s 文件中包含了完全是汇编指令的内容,表明 hello.c 文件已经被成功编译成了汇编语言。...生成文件 hello.o代码语言:shell复制gcc -c hello.s -o hello.o链接(ld)链接过程中,链接器的作用是将目标文件与其他目标文件、库文件以及启动文件等进行链接,从而生成一个可执行文件...比如,在 Intel x86 架构或者 Windows 平台下、使用 Visual C++ 编译生成的可执行文件,在同样的 Intel x86 架构/Windows 10 下运行。

    8010

    在CC++直接插入汇编代码的方法-内联汇编

    方法总结 案例1 案例2-内联汇编 内联汇编A+B 基础讲解 ---- 方法总结 在c语言直接插入汇编 C/C++中内嵌汇编(Visual Studio 2019) 案例1 #include c); return 0; } 案例2-内联汇编 内联汇编示例: Hello, World为例: #include #include...内联汇编代码不易于移植,如果你的程序打算在不同类型的机器(比如x86和Alpha)上运行,应当尽量避免使用内联汇编,这时可以使用MASM,因为MASM支持更方便的宏指令和数据指示符。...例如: __asm mov al, 4 __asm mov dx, 0xB0008 __asm out dx, al 上面的两个例子所生成的代码是相同的,但是在括号里的__asm块这种方式更具优势...另外,由于大括号里的语句和一般的MASM语句格式一样,所以可以很方便地从现有的MASM源程序里复制。 不像C或C++中的"{}",__asm块中的"{}"不会影响C或C++变量的作用范围。

    1.6K30

    逆向工厂(一):从hello world开始

    静态链接:链接器将函数的代码从其所在地(目标文件或静态链接库中)拷贝到最终的可执行程序中,整个过程在程序生成时完成。...("hello world!...\n");} 这是我们编写的打印hello world程序,是不是看起来很亲切,接下来将编译好的hello world程序用IDA反汇编,生成的代码如下图: ?...\n”压入栈,供printf函数使用,在反汇编程序代码中,如果调用的函数有参数,都是先将函数的参数先用push指令压入栈中,例如:add(int a,int b),调用add函数前,先将参数a和b压入栈...这就是hello world程序的逆向代码分析,只是举一个简单的例子,真正要逆向分析一个较大较复杂的程序还是有一定难度,需要更多的知识与经验。

    2.6K80

    Golang 汇编入门知识总结

    1.1 程序的编译过程 以 C 语言为例来说,从 hello.c 的源码文件到 hello 可执行文件,经过编译器处理,大致分为几个阶段: 编译器在不同的阶段会做不同的事情,但是有一步是可以确定的,那就是...相反,编译器使用了一种半抽象的指令集,并且部分指令是在代码生成后才被选择的。...往往在分析编译输出的汇编时,看到的就是硬件 SP 寄存器)。 PC: 实际上就是在体系结构的知识中常见的 pc 寄存器,在 x86 平台下对应 ip 寄存器,amd64 上则是 rip。...仔细观察上面的进程内存布局图就会发现,我们的代码在是存储在.text 段中的,这里也就是一种约定俗成的起名方式。实际上在 plan9 中 TEXT 是一个指令,用来定义一个函数。...4.4.2 变量声明 汇编里的全局变量,一般是存储在.rodata或者.data段中。对应到 Go 代码,就是已初始化过的全局的 const、var 变量/常量。

    2.6K40

    Rust编译过程讲解与环境准备

    -emit-llvm hello.c -S -o hello.ll # 导出文本类型的LLVM IR第二部:编译将预处理完的文件进行一些列的词法分析、语法分析、语义分析和优化后生成的汇编指令代码。...\n"第三步:汇编把汇编代码转变成机器可以执行的指令,过程相对编译阶段简单,没有复杂的语法,也不需要优化,只需要对照汇编指令和机器指令对照表一一翻译即可。...段表描述了各个段在文件中的偏移等信息。...* .text section 代码段* .data section 数据段* .bss section 未初始化的全局变量和局部静态变量,在文件中不占空间。* ...od -x ..../add # 查看ELF文件的信息clang -ccc-print-phases hello.c # 查看编译过程Rust中的编译过程通过前面的介绍,我们知道LLVM有一个好处,就是将前端和后端通过IR

    65210

    Linux内核源码分析 - 系统调用

    根据arch/x86/entry/syscalls/Makefile我们可以知道,是有对应的shell脚本,根据上面的文件来生成c版的头文件,比如下面两个。...上面的就是对应的汇编代码了,这里为了简单,省略掉了该汇编方法的其他部分。 那这段汇编代码又是在哪里调用的呢?...wrmsrl(MSR_LSTAR, (unsigned long)entry_SYSCALL_64);         ... } 在上面的方法中,我们可以看到,汇编代码entry_SYSCALL_64...有兴趣的可以分析并执行下下面的汇编代码,好好体会下整个系统调用的流程。..., world\n" 到这里,系统调用对应的kernel space部分就已经分析完毕了,下篇文章我们结合对应的c源码,看下user space的部分是如何实现的。

    5.7K22

    一文看懂eBPF|eBPF的简单使用

    为了让有 Java 经验的同学更容易接受 eBPF 技术。我们先介绍一下 Java 中的 AOP 概念。 在 AOP 概念中,有两个很重要的角色:切点 和 拦截器。...切点:程序中某个具体的业务点(方法)。 拦截器:拦截器其实是一段 Java 代码,用于拦截切点在执行前(或执行后),先运行这段 Java 代码。...编写 eBPF 程序有多种方式,比如使用原生 eBPF 汇编来编写,但使用原生 eBPF 汇编编写程序的难度较大,所以一般不建议。...为什么不能全部使用 Python 编写呢?这是因为 LLVM/Clang 只支持将 C 语言编译成 eBPF 字节码,而不支持将 Python 代码编译成 eBPF 字节码。...使用 C 编写 eBPF 程序 新建一个 hello.c 文件,并输入下面的内容: int hello_world(void *ctx) { bpf_trace_printk("Hello, World

    2.3K20

    汇编语言之GNU ARM

    每种汇编器都可以有自己的伪指令集和自己的语法 使用不同的汇编器汇编同一个cpu架构的汇编代码,所对应的指令绝对是一致的,但伪指令各有千秋 ;使用ARM官方的汇编器 AREA test, CODE...工具包 由于接下来我们选择在安卓模拟器上进行开发学习,因此我们选择arm-none-linux-eabi这套工具来进行代码的编译 工具下载 GCC工具的具体使用 伪指令和伪操作 注释 段的声明 代码段....text @代码 自定义一个段 函数或者标签的声明 数据的声明 数据的批量定义 格式如下: .rept @重复次数 @数据定义代码 .endr @结束重复定义 关于align 反汇编后的结果:...文件中引用汇编中的函数,C文件中只能使用extern伪指令: extern arm_strcpy(char *src,char*des); int main2(){ char *a="hello pangshu...b; } 第二步, 在汇编文件中引入函数,使用import或者extern伪指令 AREA code, CODE import c_sum mov R0,#1 ;第一个参数 mov R1,#2 ;

    2.2K30

    关于跨平台的一些认识

    但是实际上,hello world的编译过程是这样的: ? 我们分阶段来讨论: 预处理阶段。预处理器(cpp)来把 代码中#开头的行进行展开, 比如头文件,宏等内容,修改最初的C文件。 编译阶段。...一种汇编语言专用于某种计算机系统结构,而不像许多高级语言,可以在不同系统平台之间移植。...他们所使用的指令集不同啊, 这种芯片设计的事情,又不像TCP/IP协议那样,有国际统一的标准,甚至像intel所代表的复杂指令集,和arm为代表的精简指令集,它们指令集的设计思路就是不一样的。...也有些人会讲,为了让linux下编写的一段hello程序运行在window上,我不拿最后的编译结果hello来直接运行,我在window环境下重新用IDE建立项目,同样的源代码在window下重新运行一遍...在部分的商用虚拟机中,Java程序最初是通过解释器(Interpreter)进行解释执行的,当虚拟机发现某个方法或代码块的运行特别频繁时,就会把这些代码认定为“热点代码”(Hot Spot Code)。

    55030

    iOS开发你不知道的事-编译&链接

    0; } 在linux下只需要一个简单的命令(假设源代码文件名为hello.c): $ gcc hello.c $ ....所以汇编器的汇编过程相对于编译器来讲比较简单,它没复杂的语法,也没有语义,也不需要做指令优化,只是根据汇编指令和机器指令的对照表一一翻译就可以了。...: gcc –c hello.c –o hello.o 链接(linking)   链接通常是一个让人比较费解的过程,为什么汇编器不直接输出可执行文件而是输出一个目标文件呢?...下面让我们来看看怎么样调用ld才可以产生一个能够正常运行的Hello World程序: 注意默认情况没有gcc / 记得 : $ brew install gcc 链接相应的库 [1240] 下面在贴出我们的写出的源代码是如何变成目标代码的流程图...: [1240] 主要通过我们的编译器做了以下任务:扫描、语法分析、语义分析、源代码优化、代码生成和目标代码优化 到这我们就可以得到以下的文件,不知道你是否有和我一起操作,玩得感觉还是不错,继续往下面看

    57700

    为 a.out 举行一个特殊的告别仪式

    gcc 默认生成的 a.out 的实际格式是 ELF: $ echo 'int main(void){ return 0; }' | gcc -x c - - $ file a.out a.out: ELF...,“Linux Lab” 在 examples/assembly/x86 下提供了这样一个汇编程序。...,可以直接用标准的 hello.c,也可以用汇编,这里直接复用上面的 examples/assembly/x86/x86-hello.s,把它复制到 Linux 0.11 的磁盘中,并稍作改动即可: $.../a.out Hello, world! 如果需要编辑,记得通过 mkdir /tmp 创建一个 /tmp 目录,然后就可以用 vi 直接在 Linux 0.11 编辑代码了。.../elf-hello,会出现段错误,留待后续分解吧。 5. 小结 到这里为止,经过诸多努力,终于在 a.out 彻底被从官方 Linux 剔除之前,完成了一次运行的尝试。

    1.2K30

    物联网时代的嵌入式开发平台

    因为他们要卖东西,他们的客户,大多数还使用裸机C开发,而不像系统级CPU那样有完善的开发平台支持。他们的客户,迫切需要一个开发平台,来规避晦涩难懂的硬件驱动开发,使应用和驱动相分离。...这并不是说,物联网时代的嵌入式产品有多复杂,非RTOS不可,可是,再过几年,裸机C编程,会像现在的汇编编程那样,成为“高端技能”。...为什么呢?因为开发工具已经完成了大量的工作,有厂家的固件,完成GPIO的驱动,IDE自动生成的代码,完成了main函数之前的大量环境初始化工作。...所以,你只需要3分钟,在main函数里放一个循环改变GPIO状态的代码,一个C语言的闪灯程序就完成了。事实上,如果从0开始做,汇编完成闪灯,不知比C简单多少倍。...裸机C取代汇编语言的过程,正在裸机C和RTOS编程之间重演着,不信么?我出个“简单”的题,写一个“hello world”的嵌入式程序看看。

    4.4K111

    程序的基本概念

    编写、编译和执行一个C程序的步骤如下: 用文本编辑器写一个C程序,然后保存成一个文件,例如 program.c (通常C程序的文件名后缀是 .c ),这称为源代码(Source Code)或源文件...,就是编译器把源代码分析一遍生成可执行文件,而之后可执行文件在每次执行时就不需要再分析源代码了。...有些时候编译器的提示信息不是 error 而是 warning ,例如把上例中的 printf("Hello, world....出警告信息说明你的程序写得不够规范,可能有Bug,虽然能编译生成可执行文件,但程序的运行结果往往是不正确的,例如上面的程序运行时出了一个段错误(Segmentation fault),段错误是程序崩溃(...比如把上例中的 printf("Hello, world.\n"); 改成 printf(0); 然后编译运行: $ gcc main.c$ .

    1.1K20

    GCC、ARM-LINUX-GCC、ARM-ELF-GCC浅析

    【这个包GCC编译生成的库,前辈们为了方便大家开发,就把Glibc放到GCC中】 举例描述下上面3个包是如何进行运作的。...有一个c源文件test.c源码如下: #include int main(int argc, char *argv[]) { printf("Hello Linux!!...看到源码中的printf函数没有,这个函数在GCC中是以库函数的形式存在,这个库函数在glibc库中,在stdio.h头文件中被声明。...例如,要使用交叉工具链为ARM机器编译简单的Hello World程序,你可以运行如下所示的命令: 使用如下命令编译并测试这个代码: $ arm-linux-gcc -o hello hello.c 五...包也不一样;glibc一个c库,最终是以库的形式存在于编译器中,自然ARM所使用的glibc库跟X86同样也是不一样的咯,其它的依此类推。

    6.8K10

    Linux编译工具:gcc入门

    所谓的本地编译器,是指编译出来的程序只能够在本地环境进行运行。而gcc编译出来的程序能够在其他平台进行运行。例如嵌入式程序可在x86上编译,然后在arm上运行。...编译阶段,gcc调用不同语言的编译器,例如c语言调用编译器ccl。gcc实际上是个工具链,在编译程序的过程中调用不同的工具。汇编阶段,gcc调用汇编器进行汇编。...汇编器生成的是可重定位的目标文件,学过操作系统,我们知道,在源程序中地址是从0开始的,这是一个相对地址,而程序真正在内存中运行时的地址肯定不是从0开始的,而且在编写源代码的时候也不能知道程序的绝对地址,....s -c 通知gcc取消连接步骤,即编译源码,并在最后生成目标文件 -Wall 使gcc对源文件的代码有问题的地方发出警告 -Idir 将dir目录加入搜索头文件的目录路径 -Ldir 将dir目录加入搜索库的目录路径...-llib 连接lib库 -g 在目标文件中嵌入调试信息,以便gdb之类的调试程序调试 现在我们有源文件hello.c,下面是一些gcc的使用示例: gcc -E hello.c -o hello.i

    4.8K50

    ShellcodeTemplate:一款针对Windows的Shellcode模版工具

    关于ShellcodeTemplate ShellcodeTemplate是一款易于修改的针对Windows x64/x86的Shellcode模版工具,该工具基于TitanLdr开发,能够帮助广大研究人员将项目代码编译成一个...Shellcode百科 Shellcode是一段用于利用软件漏洞而执行的代码,实际上是十六进制形式的机器语言,大家知道机器语言是二进制的,CPU只认识二进制,因为要被直接注入到内存中,没办法编译了,所以希望...CPU可以执行,那就只能用机器代码了,一般用汇编语言写出程序,在从目标代码中提取出来。...------ Instance.Win32.MessageBoxA( NULL, GET_SYMBOL( "Hello World" ), GET_SYMBOL( "MessageBox Title..." ), MB_OK ); } 值得注意的是,正如大家所看到的那样,我们可以直接在我们的Shellcode中使用常规字符串,这是因为我们在链接的时候向我们的Shellcode中引入了.rdata字段,

    75540

    二进制基础

    做 pwn 或者 reverse 的一些基础 程序的编译与链接 编译:由 C 语言代码生成汇编代码 汇编:由汇编代码生成机器码 链接:将多个机器码的目标文件链接成一个可执行文件 Linux 下的可执行文件格式...静态存储区 code段:静态存储区 堆空间从低地址向高地址增长 栈空间从高地址向低地址增长 段和节: ·代码段包含了代码和只读数据 .test节(用户的代码实现)...磁盘上的可执行文件要先到内存,才能被 CPU 执行 从程序变为虚拟内存中 int glb; char* str = "Hello world"; int sum(int x, int y) {...) Bss: glb (存放未初始化的全局变量)(不占用磁盘空间但是占用内存空间) Data: str (保存只读、不可写、不可执行的数据) Text: main、sum、"Hello world!"...AT&T 汇编格式 Disp(base, index, scale) movq $0xffff, (%rsp) C 语言 数据类型 汇编代码后缀 char 字节 b byte short 字 w word

    36840

    VS中使用X64汇编

    需要注意的是,在X86项目中,可以使用__asm{}来嵌入汇编代码,但是在X64项目中,再也不能使用__asm{}来编写嵌入式汇编程序了,必须使用专门的.asm汇编文件来编写相应的汇编代码,然后在其它地方来调用这些汇编代码...那么,如何在VS中使用X64的汇编呢?本例子将演示如何在汇编文件中使用.c或者.cpp源文件中定义的函数和变量,以及如何在.c或者.cpp中使用汇编文件中定义的函数。...#include "stdafx.h" #include "func.h" void print1(void) { printf("hello world1\n"); } void print2...(void) { printf("hello world2\n"); } //func.h #pragma once extern "C"//防止函数被name mangling { void...;自己定义变量 .CODE func1 PROC mov r10, g_iValue;使用func.h中的外部变量 mov val1,r10;使用自定义变量 mov rax,val1 ret;如果不返回

    3.9K31
    领券