gcc 对整型和浮点型参数传递的汇编码生成特点分析 张昱 1. 相关资料 关于浮点数 (Floating-point) 的存储表示 : 浮点数的存储目前广泛采用 IEEE 754 标准 (1980 年 Intel 提出, 1985 年被 IEEE 采纳,

Similar documents
Static Enforcement of Security with Types

程序 linux/include/linux/math_emu.h 1 /* 2 * linux/include/linux/math_emu.h 3 * 4 * (C) 1991 Linus Torvalds 5 */ 6 #ifndef _LINUX_MATH_EMU_H 7 #de

Microsoft PowerPoint - lec11 [兼容模式]

CC213

修改图 7.5 中计算声明名字的类型和相对地址的翻译方案, 允许名字表而不是单个名字出现在形式为 D id : T 的声明中 即允许 a, b, c : integer 这种形式的变量声明 下面是一个 C 语言程序 : long f1( i

3 程序的机器级表示 2017 年 3 月 11 日 11: 计算机执行机器代码, 用字节序列编码低级的操作, 包括处理数据 管理存储器 读写存储在设备上的数据, 以及利用网络通信 通常情况下, 现代的优化编译器产生的代码至少与一个熟练的汇编语言程序员手工编写的代码一样有

幻灯片 1

没有幻灯片标题


C 1 # include <stdio.h> 2 int main ( void ) { 4 int cases, i; 5 long long a, b; 6 scanf ("%d", & cases ); 7 for (i = 0;i < cases ;i ++) 8 { 9

1 Project New Project 1 2 Windows 1 3 N C test Windows uv2 KEIL uvision2 1 2 New Project Ateml AT89C AT89C51 3 KEIL Demo C C File

1 CPU interrupt INT trap CPU exception

chap07.key

Microsoft PowerPoint - RuntimeEnvII [Compatibility Mode]

提纲. 1 实验准备. 2 从实模式进入保护模式. 3 小结 陈香兰 ( 中国科学技术大学计算机学院 ) 软件综合实验之操作系统 July 1, / 11

Linux kernel exploit研究和探索

需 求 拉 动 显 著 利 润 分 配 或 向 上 游 倾 斜 二 季 度 伊 始, 从 小 盘 题 材 向 大 盘 蓝 筹 的 风 格 转 换, 似 乎 刚 刚 开 始 就 又 戛 然 而 止 我 们 认 为, 虽 然 没 有 充 分 证 据 表 明 整 体 经 济 持 续 过 热, 但 局 部

C/C++ - 文件IO

!"!"!"# # $! $!%%& ( )*+, ( - %& - %"./!. - &! " # $ 0("1! 2)3!%%& %.//(( %"% - 4&%.&.55 & 5%% - 5"% - %.15 "%%%"" 6778 # # 999 6:8 :;< => %"% -

untitled


C/C++程序设计 - 字符串与格式化输入/输出

Contents 1 深 圳 大 学 经 济 学 院 学 生 代 表 大 会 章 程 2 2 优 秀 毕 业 生 评 选 细 则 7 3 议 事 规 则 8 i

(譯本)

上 海 农 商 银 行 理 财 产 品 风 险 揭 示 书 理 财 资 金, 则 客 户 面 临 产 品 期 限 延 期 调 整 等 风 险 8. 信 息 传 递 风 险 : 上 海 农 商 银 行 将 按 照 本 说 明 书 有 关 信 息 公 告 的 约 定, 进 行 产 品 信 息 披 露 客

!"# $% & $%%% ( ")*+,-./00-(11.-. $%! $ " # $ % & ( - ) +%23!"# $%%% %,.%,!" $%.! 1.% & /$ 3(,. ( /0% $%%% ( $%%% ( 3 5 /6%%%! ")*+,-./00-(11

!! "!! "! "!! "! "! "!!#$% & ()*+, -./!000$ 1-2$##0! 3

Introduction to Computer Systems /18-243, spring st Lecture, Jan. 12th

2014年大学生村官考试公共基础知识:社会革命和社会改革

朝陽科技大學八十八學年度招考碩士班簡章目錄

C/C++ - 函数

3.1 num = 3 ch = 'C' 2

Microsoft Word - 2AF63內文.doc

<4D F736F F D20B5DAC8FDCBC4D5C2D7F7D2B5B4F0B0B82E646F63>

东 华 能 源 江 苏 苏 亚 金 诚 已 报 备 因 地 域 及 审 计 时 间 安 排 等 原 因 中 兴 华 已 报 备 客 户 重 新 选 聘 会 计 师 事 务 所 亿 帆 鑫 富 立 信 已 报 备 客

商 业 城 大 华 标 准 70 万 70 万 驰 宏 锌 锗 瑞 华 标 准 140 万 150 万 亚 星 锚 链 江 苏 公 证 天 业 标 准 80 万 80

欢迎辞

金 陵 饭 店 中 兴 华 已 报 备 按 照 国 资 委 要 求 定 期 轮 换 天 衡 已 报 备 按 照 国 资 委 要 求 定 期 轮 换 *ST 中 富 中 喜 已 报 备 业 务 约 定 书 到 期 普

辉 丰 股 份 重 大 事 项, 特 停 南 方 轴 承 临 时 停 牌 德 力 股 份 临 时 停 牌 瑞 丰 光 电 临 时 停 牌 联 建 光 电 临 时 停 牌 卡 奴 迪 路 临 时 停 牌

日 涨 幅 偏 离 值 达 到 7% 的 前 五 只 证 券 : 温 氏 股 份 ( 代 码 ) 涨 幅 偏 离 值 :11.68% 成 交 量 :1752 万 股 成 交 金 额 : 万 元 机 构 专 用 机 构 专 用

上市公司股东大会投票信息公告( )

股票代码: 股票简称:*ST新梅 编号:临

昆 明 机 床 瑞 华 已 报 备 前 任 服 务 年 限 较 长 毕 马 威 华 振 已 报 备 未 与 客 户 未 就 2015 年 审 计 收 费 达 成 一 致 意 见 中 国 核 电 天 健 已 报 备 定

金 利 科 技 临 时 停 牌 凤 凰 光 学 重 要 事 项 未 公 告, 连 续 停 牌 安 源 煤 业 重 要 事 项 未 公 告, 连 续 停 牌 万 泽 股 份 临 时 停 牌 爱 康 科 技 重 大 事 项, 特 停

光 一 科 技 重 大 事 项, 特 停 茂 业 商 业 重 要 事 项 未 公 告, 连 续 停 牌 浙 富 控 股 重 大 事 项, 特 停 键 桥 通 讯 重 大 事 项, 特 停 黑 牛 食 品 重 大 事 项, 特 停

郑 州 煤 电 重 要 事 项 未 公 告, 连 续 停 牌 金 圆 股 份 重 大 事 项, 特 停 永 鼎 股 份 重 要 事 项 未 公 告, 连 续 停 牌 长 城 影 视 临 时 停 牌 天 兴 仪 表 临 时 停 牌

卧 龙 地 产 重 要 事 项 未 公 告, 连 续 停 牌 春 兴 精 工 临 时 停 牌 *ST 沧 大 重 要 事 项 未 公 告, 连 续 停 牌 天 地 源 重 要 事 项 未 公 告, 连 续 停 牌 汇 冠 股 份

金 圆 股 份 重 大 事 项, 特 停 长 城 影 视 临 时 停 牌 天 兴 仪 表 临 时 停 牌 商 赢 环 球 重 要 事 项 未 公 告, 连 续 停 牌 荣 安 地 产 临 时 停 牌 中 南 文 化

Untitled Document

证券代码:000776   股票简称:延边公路   编号:2003-00

c_cpp

<4D F736F F D20CAB5D1E BACDBBE3B1E0D3EFD1D4B5C4BBECBACFB1E0B3CCCAB5D1E92E646F63>

ROP_bamboofox.key

1 LINUX IDE Emacs gcc gdb Emacs + gcc + gdb IDE Emacs IDE C Emacs Emacs IDE ICE Integrated Computing Environment Emacs Unix Linux Emacs Emacs Emacs Un

(Microsoft Word - \277\357\262\325\252\272\246\322\266q.doc)

C/C++语言 - C/C++数据

C

CHAPTER VC#

.size main,.lfe1-main.local b.comm b,4,4.comm c,4,4.ident "GCC: (GNU) egcs /Linux (egcs release)" 修改图 6.5 中计算声明名字

C C

新版 明解C言語入門編

为 了 衡 量 一 个 算 法 时 间 效 率 上 的 优 劣, 计 算 机 科 学 中 引 入 了 时 间 复 杂 度 的 概 念 回 忆 我 们 习 惯 使 用 的 大 O 表 示 法, 我 们 说 一 个 算 法 运 行 时 间 的 界 是 O(f(n)), 所 表 示 的 意 义 是, 假

Microsoft Word - 中耳的主要疾病~中耳炎.doc

今天刚发现的, 比较简单, 于是就来简单分析下吧 该感染样本很简单, 新加了个区段放病毒执行代码, 执行病毒代码, 最后跳回原入口点来执行原文件 下面就是感染后的代码的简单分析 : ; =============== S U B R O U T I N E =====================

C++ 程序设计 告别 OJ1 - 参考答案 MASTER 2019 年 5 月 3 日 1

untitled


51 C 51 isp 10 C PCB C C C C KEIL

6 C51 ANSI C Turbo C C51 Turbo C C51 C51 C51 C51 C51 C51 C51 C51 C C C51 C51 ANSI C MCS-51 C51 ANSI C C C51 bit Byte bit sbit

滬 港 股 票 市 場 交 易 互 聯 互 通 機 制 上 市 公 司 常 問 問 題 滬 港 股 票 市 場 交 易 互 聯 互 通 機 制 ( 滬 港 通 ) 是 在 中 國 內 地 與 香 港 兩 地 證 券 市 場 建 立 的 交 易 及 結 算 互 聯 互 通 機 制 在 滬 港 通 項

ARM中C和汇编混合编程及示例.doc

Microsoft PowerPoint - compiler

untitled

Microsoft PowerPoint - 05-第五讲-寻址方式.pptx

第5章:汇编语言程序设计

2005年01月12日

download.kaoyan.com_2006ÄêÌì½ò¹¤Òµ´óѧ¸ß¼¶ÓïÑÔ³ÌÐòÉè¼Æ£¨409£©¿¼ÑÐÊÔÌâ

C++ 程式設計

新・解きながら学ぶC言語

µÚ¶þÕ µ¥´¦ÀíÆ÷Ìåϵ½á¹¹

证券投资基金信息披露XBRL标引规范第2号<半年度报告摘要>

中 公 金 融 人 简 介... 2 一 中 国 农 业 银 行 风 貌 介 绍... 3 二 中 国 农 业 银 行 秋 季 招 聘 政 策 解 读 三 2014 农 业 银 行 秋 季 校 园 招 聘 笔 试 备 考 策 略 中 公 金 融 人 精 品 课 程 介 绍..


- 2 -

C 1

<4D F736F F D D0ADD2E9B7D6CEF6CBB5C3F7BCB0B2BFB7D6CAB5CFD6D4B4B4FAC2EB2E646F63>

C++ 程序设计 告别 OJ2 - 参考答案 MASTER 2019 年 5 月 3 日 1

上 海 证 券 交 易 所 工 作 报 告 沪 港 市 场 运 行 机 制 差 异 比 较 李 丹 李 怡 芳 邓 斌 资 本 市 场 研 究 所 市 场 发 展 组 2014 年 6 月

科学计算的语言-FORTRAN95

概述 基于 Cortex-M3 内核的 STM32F103 系列单片机, 并没有浮点运算协处理器 在 STM32F103 上进行的浮点运算都是软件模拟实现 考虑到加入浮点运算库需要大约 10K 左右的 FLASH 空间 ( 即 <math.h> 对应的数学库 ), 而且浮点运算速度较慢,EC30-E

gongGaoMingCheng

untitled

Microsoft PowerPoint - 5. 指针Pointers.ppt [兼容模式]

untitled

STM32F405/07xx STM32F415/417xx (FPU)

第十章 数模转换与模数转换接口及其应用

A 6 CPI A AH % % % A 8 70% 50% A A 2 6 A A 20.1 A A A A % /15

富国周刊

Microsoft Word - CPE考生使用手冊 docx

untitled

Transcription:

gcc 对整型和浮点型参数传递的汇编码生成特点分析 张昱 1. 相关资料 关于浮点数 (Floating-point) 的存储表示 : 浮点数的存储目前广泛采用 IEEE 754 标准 (1980 年 Intel 提出, 1985 年被 IEEE 采纳,http://babbage.cs.qc.edu/courses/cs341/IEEE-754references.html ) 32 位单精度 :Bit 31 是符号位,Bits 30~23 是指数部分,Bits22~0 是尾数部分, 即有效数字部分 64 位双精度 :Bit 63 是符号位,Bits 62~52 是指数部分,Bits51~0 是尾数部分, 即有效数字部分 http://sourceware.org/binutils/docs/as/cfi-directives.html 关于 x87 FPU 编程 : x87 FPU(Floating-Point Unit) 能为图形处理 科学计算等提供高性能的浮点处理能力 它支持浮点数 整数和紧致 BCD 整数数据类型, 支持 IEEE 754 标准中为二进制浮点运算定义的浮点处理算法和异常处理体系 有关 x87 FPU 编程可参阅 : IA32 Intel Architecture Software Developer's Manual, Intel Corporation, 2003. V1: Basic Architecture Chapter 8 Programming with the x87 FPU x87 FPU 数据寄存器 : 有 8 个 80 位的数据寄存器, 编号为 0~7 80 位中 Bit79 是符号位,Bits78-64 是指数位,Bits63-0 是存放有效数字 x87 FPU 指令将这 8 个寄存器看成一个寄存器栈 汇编器允许用 ST(0) 或 ST 来表示当前的栈顶, ST(i) 表示相对于栈顶的第 i 个寄存器 x87 FPU 数据寄存器的内容不受过程调用影响 正在调用的过程可以使用 x87 FPU 数据寄存器在过程之间传递参数, 被调用的过程可以引用通过寄存器栈传递过来的参数 ; 被调用过程也可以将返回值存入 ST(0), 再将控制转移给调用者 x87 FPU 状态寄存器 : 有 1 个 16 位的状态寄存器 Bit15: busy flag; Bits 13-11: 栈顶指针, 取值范围为 0~7, 表示栈顶指向的数据寄存器的编号 ; Bits 14,10-8: 条件码 C3-C0; 关于条件码的解释可以参见 V1: Basic Architecture 的表 8-1 Bit7: ES flag 标记是否有错 ; Bit6: SF flag 标记是否是栈错误 Bits5-0: 是一组异常标志位, 依次为 PE( 精度 ) UE( 下溢 ) OE( 上溢 ) ZE( 除 0) DE( 不规范的操作数 ) IE( 无效操作 ) x87 FPU 状态寄存器可以通过 fstsw/fnstsw fstenv/fnstenv fsave/fnsave 和 fxsave 指令存入内存, 也可以通过 fstsw/fnstsw 存入整数寄存器 eax 的低 16 位 (ax 寄存器 ) 中 x87 FPU 控制字 :16 位 x87 FPU 控制字控制 x87 FPU 的精度和所使用的舍入法 (rounding method) FPU 控制字缓存在控制寄存器中, 可通过 fldcw 指令来加载到控制寄存器, 或通过 fstcw/fnstcw 指令来存入内存 Bits15-13,7-6: 保留位 Bit12: Infinity 无穷大控制位 ; Bits11-10: Rounding 舍入模式控制位 ; 00B-Round to nearest( 向最近的一边舍入 ) 01B-Round down( 向 - 方向舍入 ) 10B-Round up( 向 + 方向舍入 ) 11B-Round toward zero( 向零方向舍入,truncate 截断 )

Bits 9-8: Precision 精度控制位 ;00B- 单精度 (24 位 ) 01B- 保留 10B- 双精度 (53 位 ) 11B- 扩展双精度 (64 位 ) Bits5-0: 是一组异常标志位, 依次为 PE( 精度 ) UE( 下溢 ) OE( 上溢 ) ZE( 除 0) DE( 不规范的操作数 ) IE( 无效操作 ) 关于 CFI(Call frame information) directives: http://sourceware.org/binutils/docs/as/cfi-directives.html.cfi_sections 用于描述 CFI directives 是发射.eh_frame section, 还是.debug_frame section 缺省 为.cfi_sections.eh_frame 关于 Exception Frames( 在汇编码的.eh_frame section 中 ) 可参见 http://refspecs.linuxfoundation.org/lsb_3.0.0/lsb-core-generic-/lsb-coregeneric/ehframechpt.html DWARF Debugging Information Format, Version 4, June 10, 2010. http://www.dwarfstd.org 6.4 Call Frame Information 术语 CFA(Canonical Frame Address): 指调用者栈帧中调用点处的栈指针值 ( 这个值与当前栈帧入口处的栈指针值可能不相同 ) 2. C 源程序 floatarg.c #include <stdio.h> void f(a, b, c) short a; float b; long c; { printf("a(%p)=%d, b(%p)= %f, %x; c(%p)=%ld\n", &a, a, &b, b, (int)b, &c, c); } main() { } f(3, 1.0, 2); 3. 执行结果 a(0xffb6ec4c)=3, b(0xffb6ec40)= 1.000000, 1; c(0xffb6ec6c)=2

4. floatarg.c 对应的 IA32 汇编码和活动记录栈 如何产生汇编码 :gcc -m32 -S floatarg.c.lc0: f:.lfb0:.file "floatarg.c".section.rodata # 只读区.align 4 # printf 中使用的格式串.string "a(%p)=%d, b(%p)= %f, %x; c(%p)=%ld\n".text.globl f.type f, @function.cfi_startproc # 代码段 # 函数开始标识, 用于初始化某些内部的数据结构 pushl %ebp # 保存调用者的栈帧基址 -- 控制链.cfi_def_cfa_offset 8.cfi_offset 5, -8 %esp, %ebp # 设置新的栈帧基址 # 修改计算 CFA 所用的偏移,CFA 地址 = 偏移 + 已定义的寄存器 # 寄存器 5 以前的值保存在相对于 CFA 地址偏移为 -8 的位置.cfi_def_cfa_register 5 # 修改计算 CFA 所用的寄存器, 设成 5 pushl %ebx # 保存 ebx 寄存器的值 subl $84, %esp # 分配临时数据区 8(%ebp), %eax # 将调用者传的第 1 个参数 (long,4 字节 ) 保存到 eax 寄存器 fldl 12(%ebp) # 将调用者传的第 2 个参数 (double,8 字节 ) 保存到 FPU 寄存器 movw %ax, -12(%ebp) # 将 eax 的低 16 位保存到 -12(%ebp) 开始的 2 个字节 -- 即 a fstps -16(%ebp) # 从 FPU 寄存器栈取 float 数存入 -16(%ebp) 开始的 4 字节 -- 即 b flds -16(%ebp) # 将 -16(%ebp) 的 float 数加载到 FPU 寄存器 fstps -24(%ebp) # 从 FPU 寄存器栈取 float 数存入 -24(%ebp) 开始的 4 字节 20(%ebp), %ebx # 取调用者传的第 3 个参数 (long,4 字节 ) 存入 ebx-- 形参 c.cfi_offset 3, -12 # 将 FPU 控制字设置成 Round toward zero (truncate, 浮点数向整数值转换 ) 模式, 计算 (int)b; # 再将 FPU 控制字恢复到设置前的状态 flds -24(%ebp) # 加载起址为 -24(%ebp) 的 float 数到 FPU 寄存器 -- 形参 b 的值 fnstcw -18(%ebp) # 将 FPU 控制字保存到 -18(%ebp) 开始的 2 个字节 movzwl -18(%ebp), %eax # 按零扩展方式将 -18(%ebp) 开始的 2 字节数存入 4 字节的 eax movb $12, %ah # 将 12 存入 eax 的低 16 位中的高 8 位, 旨在将 FPU 控制字中的 # 2 个舍入模式控制位设为 11B, 即设为 Round toward zero movw %ax, -20(%ebp) # 将 eax 低 16 位保存的新控制字存入 -20(%ebp) fldcw -20(%ebp) # 将起址为 -20(%ebp) 的 2 字节数加载到 FPU 控制寄存器 # 从而 FPU 的舍入模式设置为 Round toward zero 浮点数转换成整数 fistpl -28(%ebp) # 将 ST(0) 寄存器的值转换成整数, 存入 -28(%ebp)---(int)b

fldcw -18(%ebp) # 将 -18(%ebp) 保存的原控制字加载到 FPU 控制寄存器 # 即恢复到原来的 FPU 控制字 -28(%ebp), %ecx # 将 -28(%ebp) 开始的 4 字节存入 ecx---(int)b flds -24(%ebp) # 将 -24(%ebp) 开始的 float 数存入 FPU 寄存器栈 ---- 形参 b 的值 #short 型的 a 作为实参, 需提升到 long 型, 保存到 edx 中 movzwl -12(%ebp), %eax # 按零扩展方式将 -12(%ebp) 开始的 2 字节数 ( 即形参 a) 存入 eax movswl %ax, %edx # 按符号扩展方式将 ax 寄存器的值存入 edx # 以下处理 printf 调用的实参入栈 $.LC0, %eax # 将格式串的起址存入 eax %ebx, 32(%esp) # 将形参 c 的值存入 32(%esp) 第 8 个实参, 即 c leal 20(%ebp), %ebx # 将 20(%ebp)( 即形参 c 的存储单元 ) 的有效地址存入 ebx %ebx, 28(%esp) # 将 ebx 的内容存入 28(%esp) -- 第 7 个实参, 即 &c %ecx, 24(%esp) # 将 ecx 的内容存入 24(%esp) 第 6 个实参, 即 (int)b fstpl 16(%esp) # 按 double 型取 ST(0) 存入 16(%esp) 存入第 5 个实参, 即 b # 提升成 double 型 leal -24(%ebp), %ecx # 将 -24(%ebp) 的有效地址存入 ecx, 即 &b %ecx, 12(%esp) # 存入 12(%esp) -- 第 4 个实参, 即 &b %edx, 8(%esp) # 将 edx 的内容存入 8(%esp) -- 第 3 个实参, 即 a( 提升成 long) leal -12(%ebp), %edx # 将 -12(%ebp) 的有效地址存入 edx, 即 &a %edx, 4(%esp) # 将 edx 的内容存入 4(%esp) --- 第 2 个实参, 即 &a %eax, (%esp) # 将 eax 的内容存入 (%esp) --- 第 1 个实参, 即格式串起址 $.LC0 call printf # 调用 printf # 以下是 f 函数调用返回序列 addl $84, %esp # 回收 84 字节的空间 ( 局部数据和临时数据区 ) popl %ebx # 恢复 ebx 的值.LFE0: main:.lfb1:.cfi_restore 3 # 恢复 CFI 寄存器 3 的值, 使之恢复到函数开始处时的值 popl %ebp # 恢复旧的栈帧基址 ( 即调用者的栈帧基址 ).cfi_def_cfa 4, 4.cfi_restore 5 ret.cfi_endproc.size f,.-f.globl main.type main, @function.cfi_startproc # 由 CFI 寄存器 4 和偏移 4 计算 CFA # 恢复 CFI 寄存器 5 的值, 使之恢复到函数开始处时的值 # 返回到调用者执行 # 函数结束标识

.LFE1: pushl %ebp # 保存调用者的栈帧基址.cfi_def_cfa_offset 8.cfi_offset 5, -8 %esp, %ebp # 设置当前活动记录的栈帧基址.cfi_def_cfa_register 5 andl $-16, %esp # 栈顶指针按 subl $16, %esp # 分配 16 字节的临时数据区 $2, 12(%esp) # 2 存入 12(%esp) 开始的 4 个字节 --f 的第 3 个参数 2 fld1 # 1 存入 FPU 寄存器栈 fstpl 4(%esp) # 从 FPU 寄存器取 double 数到 4(%esp) 开始的 8 个字节 # ---f 的第 2 个参数 1.0 $3, (%esp) # 3 存入 (%esp) 开始的 4 个字节 --f 的第 1 个参数 3 call f leave.cfi_restore 5.cfi_def_cfa 4, 4 ret.cfi_endproc.size main,.-main.ident "GCC: (Ubuntu/Linaro 4.6.3-1ubuntu5) 4.6.3".section.note.GNU-stack,"",@progbits

活动记录栈高地址端 ebp 2(4 字节,long) 1.0(8 字节 double) 3(4 字节,long) 返回地址控制链 :main 的 ebp 保存旧 ebx 值 main 的活动记录 f 的活动记录 84 字节的局部和临时数据区 0-8(ebp) 4-12(ebp) 形参 a (short) 8 第 2 个参数 1.0 转换成 float -16(ebp) 12 原 FPU 控制字 -20(ebp) 新 FPU 控制字 ( 扩展双精度 ) -24(ebp) 16 形参 b (float) 20 (int)b -28(ebp) 24 未用 56 52 48 存放 f 调 44 用的函数的实 40 参 36(esp) 32(esp) 28(esp) 24(esp) 36 未用 c 的值 52 &c 的值 (int)b 的值 (double)b 的值 16(esp) 12(esp) 8(esp) 4(esp) esp 68 &b 的值 (long)a 的值 &a 的值 $.LC0 的值 84

5. 进一步的思考 如果将 floatarg.c 略做修改, 即改成 floatarg1.c, 编译产生的汇编码如下面 floatarg1.s 所示, 试自行分析并 画出活动记录栈的布局 floatarg1.c #include <stdio.h> void f(a, b, c) short a; float b; long c; { printf("a(%p)=%d, b(%p)= %f, %x; c(%p)=%ld\n", &a, a, &b, b, (int)b, &c, c); } main() { } short a = 3; float b =1.0; long c=2; f(a, b, c); floatarg1.s.file "floatarg1.c".section.rodata.align 4.LC0:.string "a(%p)=%d, b(%p)= %f, %x; c(%p)=%ld\n".text.globl f.type f, @function f:.lfb0:.cfi_startproc pushl %ebp.cfi_def_cfa_offset 8

.cfi_offset 5, -8 %esp, %ebp.cfi_def_cfa_register 5 pushl subl movw %ebx $68, %esp 8(%ebp), %eax %ax, -12(%ebp) 16(%ebp), %ebx.cfi_offset 3, -12 flds 12(%ebp) fnstcw -10(%ebp) movzwl movb movw fldcw -10(%ebp), %eax $12, %ah %ax, -14(%ebp) -14(%ebp) fistpl -20(%ebp) fldcw flds movzwl -10(%ebp) -20(%ebp), %ecx 12(%ebp) -12(%ebp), %eax movswl %ax, %edx leal fstpl leal leal $.LC0, %eax %ebx, 32(%esp) 16(%ebp), %ebx %ebx, 28(%esp) %ecx, 24(%esp) 16(%esp) 12(%ebp), %ecx %ecx, 12(%esp) %edx, 8(%esp) -12(%ebp), %edx %edx, 4(%esp)

%eax, (%esp) call addl popl printf $68, %esp %ebx.cfi_restore 3 popl %ebp.cfi_def_cfa 4, 4.cfi_restore 5 ret.cfi_endproc.lfe0:.size f,.-f.globl main.type main, @function main:.lfb1:.cfi_startproc pushl %ebp.cfi_def_cfa_offset 8.cfi_offset 5, -8 %esp, %ebp.cfi_def_cfa_register 5 andl subl movw $-16, %esp $32, %esp $3, 30(%esp) $0x3f800000, %eax %eax, 20(%esp) $2, 24(%esp) movswl 30(%esp), %eax 24(%esp), %edx %edx, 8(%esp) 20(%esp), %edx

%edx, 4(%esp) %eax, (%esp) call f leave.cfi_restore 5.cfi_def_cfa 4, 4 ret.cfi_endproc.lfe1:.size main,.-main.ident "GCC: (Ubuntu/Linaro 4.6.3-1ubuntu5) 4.6.3".section.note.GNU-stack,"",@progbits

活动记录栈高地址端 ebp 2(4 字节,long) 1.0(8 字节 double) 3(4 字节,long) 返回地址控制链 :main 的 ebp 保存旧 ebx 值 main 的活动记录 f 的活动记录 84 字节的局部和临时数据区 0-8(ebp) 4-12(ebp) 形参 a (short) 8 第 2 个参数 1.0 转换成 float -16(ebp) 12 原 FPU 控制字 -20(ebp) 新 FPU 控制字 ( 扩展双精度 ) -24(ebp) 16 形参 b (float) 20 (int)b -28(ebp) 24 未用 56 52 48 存放 f 调 44 用的函数的实 40 参 36(esp) 32(esp) 28(esp) 24(esp) 36 未用 c 的值 52 &c 的值 (int)b 的值 (double)b 的值 16(esp) 12(esp) 8(esp) 4(esp) esp 68 &b 的值 (long)a 的值 &a 的值 $.LC0 的值 84