gcc 内嵌汇编的学习笔记 IV

gcc 与 汇编 gcc 只支持AT&T格式的汇编。AT&T 386 汇编与intel格式的差异:在intel格式中大多使用大写字母,而在AT&T格式中都使用小写字母在AT&T格式中,寄存器名要加上%号作为前缀,而在intel格式中则不带前缀在AT&T的386汇编语言中,指令的源操作数与目标操作数的顺序与在intel的386汇编语言中正好相反,     在intel格式中是目标在前,源在后,而在AT&T格式中则是源 阅读详情

             gcc 内嵌汇编的学习笔记 IV
                             --函数调用
  作者:ShellEx. 
  ShellEx.cn && blog.youkuaiyun.com/shellex 版权所有
 没有经验,还是通过反汇编出来的代码来学习。先写一个简单的函数
调用的C++ code Sample:

#include <stdio.h>
int Add(int a, int b) {
 return a + b;
}
int main() {
 int in1 = 0,in2 = 0, out =0 ;
 printf("PLZ input 2 Number:(x1, x2) /n");
 scanf("%d, %d", &in1, &in2);
 out = Add(in1, in2);
 printf("out = %d",out);
 return 0;
}
///////////////////////////////////////////////////////////////
察看了得出的汇编代码,有几个发现:
i. 对于不同的编译方法(用纯C,C++)得出的函数名符号是不同的。这一
 点大家早就知道了。因为这是很多C++编译器实现函数重载的基础。
 对于g++,函数标示会变成形如"__Z3Addii"这样的东西。前缀不知道
 是虾米东西,但是后缀是参数列表的参数类型名缩写。
ii. 编译器会在汇编代码文件里面加入新标示用于标示函数:
 .globl _Add
  .def _Add; .scl 2; .type 32; .endef
 _Add:
  pushl %ebp
  movl %esp, %ebp
  movl 12(%ebp), %eax
  addl 8(%ebp), %eax
  popl %ebp
  ret
 如果函数是static的那么就是这样:
  .def _Add; .scl 3; .type 32; .endef
 _Add:
  pushl %ebp
  movl %esp, %ebp
  movl 12(%ebp), %eax
  addl 8(%ebp), %eax
  popl %ebp
  ret 

接着我看看调用函数Add的汇编代码:
 movl -8(%ebp), %eax
 movl %eax, 4(%esp)
 movl -4(%ebp), %eax
 movl %eax, (%esp)
 call _Add
 movl %eax, -12(%ebp)
没有传说中的压栈操作。但是效果是一样的。因为%esp保存着栈顶指针。
相当于: 
 movl -8(%ebp), %eax
 push %eax
 movl -4(%ebp), %eax
 push %eax
 call _Add
 movl %eax, -12(%ebp)
从右往左依次把参数压栈。call _Add后,可以看到结果被放在eax里面。
我记得VC好像就用push的多,而gcc则总是默认用mov。(Borland好像也
喜欢用mov),记不清了。

接着写一段汇编调用C函数的代码:

#include <stdio.h>
int Add(int a, int b) {
 return a + b;
}
int main() {
 int in1 = 0,in2 = 0, out =0 ;
 printf("PLZ input 2 Number:(x1, x2) /n");
 scanf("%d, %d", &in1, &in2);
 int (*pf)(int,int) = Add;
 asm volatile(
  "nop #FunTest  /n/t"  
  "mov  %3, 4(%%esp) /n/t"
  "mov  %2, (%%esp)  /n/t"
  "call *%0    /n/t"
  "mov  %%eax, %1  /n/t"
  :"+r"(pf),"+r"(out)
  :"r"(in1),"r"(in2)
  :"esp","eax"
 );
 //OllyDbg
 printf("out = %d/n",out); 
 return 0;
}
///////////////////////////////////////////////////////////////
在 AT&T 汇编格式中,绝对转移和调用指令(jump/call)的操作数前要
加上*作为前缀,所以我在%0前加了*。而intel汇编是不需要的。在调用
函数时,我用了函数指针,因为直接用函数名会报错。当然,其实这样
写也可以:
 asm volatile(
  "nop #FunTest  /n/t"  
  "mov  %2, 4(%%esp) /n/t"
  "mov  %1, (%%esp)  /n/t"
  "call _Add   /n/t"
  "mov  %%eax, %0  /n/t"
  :"+r"(out)
  :"r"(in1),"r"(in2)
  :"esp","eax"
 );
但是这样写的前提是你知道生成的函数标识是什么才行。。。
PS:发现一点小问题,有时在gcc 中生成不了的内嵌汇编代码模板在g++
里面可以通过,直到用as编译时才会报错,原因不明。比如说如果在调
用函数时不用函数指针pf而用直接用函数名Add倒入汇编模板,就会出现
这样的问题。
 
  ShellEx.cn && blog.youkuaiyun.com/shellex 版权所有
 

gcc之编译链接原理 文章目录1. 概述2. 1. 概述      Windows环境下的开发同事,对于“目标文件”概念的理解或多或少有些陌生,因为大多数都是基于IDE(Integrated Development Environment)集成开发环境进行项目开发。如常用到的 IntelliJ IDEA、Visual Studio、Eclipse 等等。当某函数功能开发完成之后,直接鼠标点击构建(Build)然后就会生... 阅读详情

相关推荐

GCC内嵌汇编语法

如何在GCC实现C语言中内嵌汇编,很好的资料

【高级阶段】第21章 汇编语言

ret指令实现子程序的返回机制,ret指令弹出栈中保存的指令地址,然后无条件转移到保存的指令地址执行。通常用标签(label)指示程序中的指令地址,在x86汇编代码中,可在任何指令前加入标签。指令中可以有一个、两个或者三个操作数,也可没有操作数,根据一条指令有几个操作数地址,可将指令分为零地址指令、一地址指令、二地址指令、三地址指令、四地址指令略。)型指令:操作时都是涉及内存单元,参与操作的数都是放在内存里,从内存某单元中取操作数,操作结果存放至内存另一单元中,因此机器执行指令需要多次访问内存。

weixin_52297942的博客 879

BMC的风扇控制 (Fan speed control)

这篇文章是我刚开始做风扇功能的时候写的,因为那时候都找不到主管要我报告的内容,所以报告完就顺便整理一下,最近因为在修控制学,之后应该会再补一篇和控制学相关的内容 (如果有空的话) BMC的风扇控制算一个蛮重要的功能,那这个功能包含了"TACH"和"PWM"这两个常用讯号怎么解读,还有最常用的控制演算法"PID(closed loop)"和"Stepwise(openloop)",而另外的Error control ,因为每家做法不同,就不会在这边作介绍 ##实作程式码是来自Facebook的openBM

yeiris的博客 1万+

X64下的内联汇编避坑之“mov报错?”

(X64下的内联汇编避坑之“mov报错?”) 标题为何32位的代码到64位软脚了? 首先我们先回顾下关于x64在C标准库中定义的一系列长度变化 以最常用的size_t为例,在64位系统下的size_t也变成了64位: typedef long size_t; 因此,对于有些内嵌汇编教程中的movl指令就必须进行相应的变动;而具体的变动则应当参考man页中的定义进行相关的变动。 举个栗子,有如下代码段 int main(void) { int str_len = 15; const

qq_44413572的博客 4569

什么是深度展开网络?如何将迭代算法的每一次迭代展开成深度网络对应的一层?深度展开网络进行端对端训练,其中端对端是什么意思?

在深度学习和机器学习的背景下,“端到端”(End-to-end)训练指的是将输入数据直接映射到最终输出的过程,而不需要任何中间的手动数据预处理或特征工程。- **自然语言处理**:端到端自然语言处理系统可以将自然语言输入直接转化为计算机可理解的语言输出,而不需要对语言进行分解和转化。- **推荐系统**:通过使用深度神经网络,端到端推荐系统可以直接根据用户历史行为预测其未来的兴趣爱好,并推荐相应的产品或服务。4. **直接映射**:从输入到输出的直接映射,中间没有任何拆分或分解的过程。

m0_67897882的博客 5423

Xilinx ERNIC RoCEv2 FPGA实现与QP队列深度解析

本文深入解析Xilinx ERNIC RoCEv2在FPGA上的实现,重点剖析QP队列对的管理机制与深度优化策略。通过Verilog代码示例和工程实战,详细介绍了如何实现高吞吐量、低延迟的RDMA硬件卸载方案,为金融交易和数据中心应用提供性能优化指导。

solidity8miner的博客 875

linux内核研究笔记3(move_to_user_mode)

内核版本:linux 0.11 函数调用:main.c第137行 函数定义:system.h第1到14行 #define move_to_user_mode() \ __asm__ ("movl %%esp,%%eax\n\t" \ "pushl $0x17\n\t" \ "pushl %%eax\n\t" \ "pushfl\n\t" \ "pushl $0x0f\n\t" \ ...

sunxiaohusunke的专栏 557

基于simulink的预测电流控制策略的三相逆变器仿真

本文详细介绍了在Simulink中实现基于预测电流控制策略的三相逆变器仿真方法。主要内容包括:准备工作(安装必要软件及工具箱)、构建三相逆变器基础模型、设计预测电流控制器(包含状态空间建模和控制器设计)、实现控制逻辑、添加示波器观察输出、配置仿真参数以及运行仿真分析结果。通过MATLAB代码示例和Simulink模块说明,展示了如何选择最优开关状态来最小化电流误差。该仿真方法为研究快速响应、高精度的逆变器控制提供了实用工具,但需注意实际应用中可能需要的调试工作。

amy_mhd的博客 272

ARM汇编1:如何在C语言中使用汇编

我最近对ARM的NEON编程有兴趣,主要是为了想学习一些矩阵计算加速相关的知识。但是我又不想写纯粹的汇编语言,我想在C语言中嵌入汇编来使用。 经过检索学习,我找到两种可行的方式。我在阅读ncnn代码的时候,发现下面这两种方式都有用到。为了后续能愉快的阅读ncnn代码,将相关知识做个简单的整理。

yuanlulu的博客 1756

Java调用OpenDDS(2)-理解OpenDDS自带的Messager示例

理解Messenger

zhangzl419 1660

卷积层 (Convolutional Layer) 原理与代码实例讲解

卷积层 (Convolutional Layer) 原理与代码实例讲解 关键词:卷积层,卷积操作,滤波器,特征提取,神经网络 1. 背景介绍 卷积神经网络 (Convolutional N

欢迎来到我的优快云空间!这里聚焦AI大模型应用实战,分享前沿技术、实战案例与开发经验。 769

GCC下载&安装

1. 下载 H2+b3y-1a]  WTJ/u001E{ /u001BM$  在GCC网站上(http://gcc.gnu.org/)或者通过网上搜索可以查找到下载资源。目前GCC的最新版本为 3.4.0。可供下载的文件一般有两种形式:gcc-3.4.0.tar.gz和gcc-3.4.0.tar.bz2,只是压缩格式不一样,内容完全一致,下载其中一种即可。 Xb/u001CB/u001F( b5L

海纳百川的专栏 1万+

从后端角度浅谈抗辐射设计----三模冗余(TMR)

三模冗余设计(TMR),是最常用的一种容错技术,三个模块采取相同的操作,以多数相同的输出作为表决系统的正确输出,即3取2,因为三个模块是相互独立的,而其中两个模块同时出错的概率是极小的,因此便可保证系统输出的可信度。然而这个设计也会存在面积浪费,功耗的增加,而且由于是冗余的设计,在后续进行综合或者pr的时候会被工具优化,因此需要对模块进行don’t touch设置;通过增值表得到,逻辑关系表达式为:Q=(Q1&Q2)|(Q1&Q3)|(Q2&Q3),通过工艺库的stdcell进行搭建,得到如下电路。

芯冰乐 326

Linux基础篇 -- gcc/g++的使用以及动静态库的区别

1.编译过程 2.代码在gcc下生成 3.库函数 静态库和动态库 4.gcc选项

qq_53413129的博客 506

从扩散到流匹配:具身智能中的生成模型原理与实现细节(具身智能/VLA/机器人面试常考)

本文探讨了生成模型在具身智能中的应用,重点对比了扩散模型和流匹配(Flow Matching)两种方法。扩散模型通过逐步加噪和去噪过程学习数据分布,建模能力强但采样速度慢;而Flow Matching直接学习连续向量场,更适合实时轨迹规划等需要快速连续生成的任务。文章还分析了自注意力机制的优势、ROS1/ROS2通信架构差异,并提供了Flow Matching的PyTorch实现代码。这些生成模型使机器人系统能够处理不确定性、多模态信息和连续控制问题,从传统的确定解转向更灵活的分布建模范式。

m0_51738372的博客 234

数学建模模型总结

这是本人在两年内准备参加数学建模竞赛搜集到的模型资料,已经经过了本人的筛选和整理,希望能够对准备参加数学建模竞赛的学弟学妹们提供一些帮助!

【Linux】基础开发工具——gcc/g++使用

通过本篇博客的学习,可以让你初步了解gcc/g++的使用

Brant_zero的博客 393

IDEA的使用指南

IDEA基于java的使用手册,可以最快速的上手,在使用中不断的丰富自己的使用技巧.

Docker配置任意版本编译环境(GCC升级、降级、指定版本)

引(时间紧迫的朋友可以跳过该部分) 你是不是正被需要指定GCC版本的项目弄的焦头烂额? 你是不是正被GCC编译安装的下载速度所限制? 你是不是正被编译安装时报出的各种错误扰乱了心智? 现在有工具可以解救这种处境下的人类了——Docker。 说明 后面并没有用到dockerfile,因为从追求简易的角度出发,所以对于掌握docker的朋友来说,理解更加容易。 准备工作 首先需要安装Docker...

koko_TT的博客 1万+

pscad IEEE标准系统搭建说明

pscad IEEE标准系统搭建说明,包含典型的IEEE 9节点、14节点、30节点、39节点和118节点系统。内含标准测试系统的原始数据和潮流结果。

老版QQ原生表情gif动态

这是老版的QQ表情,不过全是动态的的,Windows照片查看器是不会动的,可以右击用浏览器打开查看,再说一遍是老版的,只是分享给宁愿用老版也要动态的人。

Docker下构建gcc编译环境

本文转自:https://blog.youkuaiyun.com/weixin_44344462/article/details/88525655 例如我本次需要GCC-6.3.0的环境,在Docker安装完毕,启动后在终端键入以下命令,拉取一个指定编译环境的镜像。 docker pull gcc:6.3.0 下载后的gcc:6.3.0实际上是一个Linux环境,运行该镜像并创建一个路径后面用来共享本机的...

4290

32位模式下使用64位寄存器注意事项

1. 汇编环境龙芯2E平台32位OS模式下,要使用64位寄存器可以在汇编代码里直接 用,运算时使用d开头的指令(double-word, 64bit),作用于寄存器即可。如:dadd, dsub, dmult, dmultu, ddiv, dsll, dsrl, dsra 等等。访问存储器可以直接使用ld/sd, ldc1/sdc1使用这些指令前,先用伪操作 .set mips3 告诉汇编器下面的

四度空间 4430

[MMX指令版]黑白棋行动力的计算--原始版本(gcc汇编版)

WZebra作者Gunnar Andersson提供的原始版本,具体的网页我已经记不住了,好像WZebra主页http://www.nada.kth.se/~gunnar/othello.html已经访问不了了,我也好久好久不关注WZebra了。使用了bitboard技术和MMX指令,这个是原始版本(gcc汇编版),必须在gcc下才可能编译。作者曾说不喜欢VC的汇编格式(确切的说是Intel的习惯

shines77 的博客 3059

MinGW:GCC编译C语言,生成和调用dll

/Step2. GCC 编译(main.c)+连接动态库(*.dll),生成可执行(*.exe)// -shared -o生成dll, -xc忽略其后所有文件后缀名(全当作.c源文件)// -o生成目标文件, -xnone停止忽略后缀名。//Step1. GCC 编译(*.c)生成动态库(*.dll)//另外:若用正常后缀名(*.c),上述更精简。Part II: 编译用到的源文件。// 这两条作用相同,任选其一。// 工具=MinGW-W64。//Step3. 运行目标文件。

weixin_44544930的博客 4235

windows下安装gcc以及make

安装gcc 1、首先需要安装编译器 根据编译文件的版本去选择,下面有打包好, 不能用的话就需要去官网下载了! 链接:https://pan.baidu.com/s/18mXwQ-ijhUjk3nIyp4cwlw 提取码:3iv5 官网下载链接:https://sourceforge.net/projects/ming/?source=typ_redirect 2、安装,双击运行exe文件 等待下载完… 安装完成后如下页面: 将上面的所有包勾选上,并下载 安装完成后,close掉即可 配置环境变量: 默认的安

weixin_44537595的博客 1316

GCC 编译器上游合并对 Haiku OS 的支持

haiku configure target,并对 GCC 中现有的 BeOS 代码的构建系统进行一些修改。Haiku 操作系统的开发者一直在为在其平台上支持 GNU Compiler Collection (GCC) 编写补丁。Haiku 前身是 BeOS 操作系统,在 BeOS 被收购后更名为 Haiku。“Haiku” 一词来源于日语 “俳句”,因 BeOS 里大量输出信息使用俳句的形式而得名。从提交信息来看,这次向 GCC git 主线的 commit 增加了对 Haiku 操作系统的支持。

Jdjdjjdjdjdje的博客 198

开源项目“Iv”详解及新手常见问题解决方案

开源项目“Iv”详解及新手常见问题解决方案 项目基础介绍 “Iv”是一个基于C++编写的ECMAScript(ECMA262 5.1版)词法分析器、解析器、解释器、虚拟机以及方法即时编译器。本项目受到了V8、SpiderMonkey、JavaScriptCore等知名JavaScript引擎的启发。它包含了多个子模块,如LV5引擎、Railgun寄存器型VM与编译器、Breaker上下文线程化JI...

gitblog_00031的博客 432

15、GCC/G++ 及动态库与静态库简介

GCC/G++ 及动态库与静态库简介

Man 1641
上一篇: gcc 内嵌汇编的学习笔记 III
下一篇: 扩展你的WIndows标准控件
ShellEx
博客等级 码龄21年 4粉丝 43原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值