- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我正在尝试为 GCC 编译的应用程序编写一个程序集检测器模块,作为安全框架的一部分。为了提高模块的性能,我需要尽可能地减少动态跳转/动态函数调用。这些基本上使用一些动态指针(例如寄存器)来执行跳转或调用函数。
当前的 GCC 编译器在多次调用同一个函数(代码中的某个标签)时,将标签加载到一个寄存器中,然后在需要调用该函数时跳转到该寄存器。这当然比每次都跳转到同一个标签(更小的代码和更少的时钟周期)要快得多,但是,正如我所提到的,我的框架效率低下。
为了给你一个我想避免的例子,这里有一个代码片段:
MOV #function_label, R10. #Copy the label to the R10 register
CALL R10
...
...
CALL R10
...
...
CALL R10
虽然我希望 GCC 执行以下操作:
CALL #label_function
...
...
CALL #label_function
...
...
CALL #label_function
请注意,我实际上使用的是 mspgcc,这是 MSP430 系列微 Controller 的 GCC 编译器,但基于 GCC 应该不会有太大区别。
最佳答案
使用 -fno-function-cse
不要对函数地址进行公共(public)子表达式消除。 GCC manual :
-fno-function-cse
Do not put function addresses in registers; make each instruction that calls a constant function contain the function’saddress explicitly.
This option results in less efficient code, but some strange hacksthat alter the assembler output may be confused by the optimizationsperformed when this option is not used.
The default is -ffunction-cse
gcc -O1 -fverbose-asm
asm 输出以查看
-O1
的所有优化选项暗示(GCC 在 asm 注释中列出)。
-O1 -fno-...
所有版本都编译为 3
call
每个指令都带有符号名称,确认其中一个是我想要的,所以我只需要通过将
-fno-
的列表一分为二来缩小范围。选项
tr ' ' '\n' | sed -e 's/-f/-fno-/' -e '/;/d'
转
-f
选项变成它们的否定形式。我将整个 asm 注释块复制/粘贴到终端中的该命令中,并将结果复制/粘贴到 Godbolt 上的 GCC 选项框中。 (与
-O1
一起。
-O0
是一种用于一致调试的特殊反优化模式,因此即使使用正确的选项,跨语句优化可能永远不会在
-O0
处处于事件状态。这就是为什么我需要否定这些选项的原因在没有
-O1
的情况下尝试正数形式)
-f
选项,然后将其缩小到一个。 (当我在该组中看到名称
-fno-function-cse
时,我认为这听起来像是正确的事情。幸运的是,如果您了解编译器/优化术语,GCC 选项确实具有有意义的名称。)
mov
- 立即或 7 字节 RIP 相关
lea
(x86-64) 可以设置多个 2 字节
call
指示。
-ffunction-cse
显式启用,GCC 根本不会为 x86-64 或 ARM 拇指做这种优化,即使在它已经使用 GOT 中的函数指针的情况下。 (在 Godbolt 上的 x86-64
gcc -Os -fPIE -fno-plt -ffunction-cse
。我什至告诉 GCC 优化代码大小;保存/恢复像 RBX 这样的调用保留寄存器以用于 2 字节
call rbx
而不是 6 字节
call [RIP+rel32]
会即使在推送/弹出 RBX(每个 1 个字节)并加载到 RBX(一个具有 RIP 相对寻址模式的 mov)所需的额外指令之后,也可以节省大小。)
-Os
的遗漏优化。 ,特别是对于像
-mcpu=cortex-m3
这样的“简单”内核的 ARM Thumb它甚至可能没有分支预测器。
-fPIE -fno-plt
的寄存器中,用于没有“隐藏”可见性的函数,即该函数可能仅位于共享库中。即使使用
-fno-function-cse
也会发生这种情况。
https://godbolt.org/z/f3MP56. )
关于assembly - 防止 GCC 使用动态跳转/函数调用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/64150636/
C语言sscanf()函数:从字符串中读取指定格式的数据 头文件: ?
最近,我有一个关于工作预评估的问题,即使查询了每个功能的工作原理,我也不知道如何解决。这是一个伪代码。 下面是一个名为foo()的函数,该函数将被传递一个值并返回一个值。如果将以下值传递给foo函数,
CStr 函数 返回表达式,该表达式已被转换为 String 子类型的 Variant。 CStr(expression) expression 参数是任意有效的表达式。 说明 通常,可以
CSng 函数 返回表达式,该表达式已被转换为 Single 子类型的 Variant。 CSng(expression) expression 参数是任意有效的表达式。 说明 通常,可
CreateObject 函数 创建并返回对 Automation 对象的引用。 CreateObject(servername.typename [, location]) 参数 serv
Cos 函数 返回某个角的余弦值。 Cos(number) number 参数可以是任何将某个角表示为弧度的有效数值表达式。 说明 Cos 函数取某个角并返回直角三角形两边的比值。此比值是
CLng 函数 返回表达式,此表达式已被转换为 Long 子类型的 Variant。 CLng(expression) expression 参数是任意有效的表达式。 说明 通常,您可以使
CInt 函数 返回表达式,此表达式已被转换为 Integer 子类型的 Variant。 CInt(expression) expression 参数是任意有效的表达式。 说明 通常,可
Chr 函数 返回与指定的 ANSI 字符代码相对应的字符。 Chr(charcode) charcode 参数是可以标识字符的数字。 说明 从 0 到 31 的数字表示标准的不可打印的
CDbl 函数 返回表达式,此表达式已被转换为 Double 子类型的 Variant。 CDbl(expression) expression 参数是任意有效的表达式。 说明 通常,您可
CDate 函数 返回表达式,此表达式已被转换为 Date 子类型的 Variant。 CDate(date) date 参数是任意有效的日期表达式。 说明 IsDate 函数用于判断 d
CCur 函数 返回表达式,此表达式已被转换为 Currency 子类型的 Variant。 CCur(expression) expression 参数是任意有效的表达式。 说明 通常,
CByte 函数 返回表达式,此表达式已被转换为 Byte 子类型的 Variant。 CByte(expression) expression 参数是任意有效的表达式。 说明 通常,可以
CBool 函数 返回表达式,此表达式已转换为 Boolean 子类型的 Variant。 CBool(expression) expression 是任意有效的表达式。 说明 如果 ex
Atn 函数 返回数值的反正切值。 Atn(number) number 参数可以是任意有效的数值表达式。 说明 Atn 函数计算直角三角形两个边的比值 (number) 并返回对应角的弧
Asc 函数 返回与字符串的第一个字母对应的 ANSI 字符代码。 Asc(string) string 参数是任意有效的字符串表达式。如果 string 参数未包含字符,则将发生运行时错误。
Array 函数 返回包含数组的 Variant。 Array(arglist) arglist 参数是赋给包含在 Variant 中的数组元素的值的列表(用逗号分隔)。如果没有指定此参数,则
Abs 函数 返回数字的绝对值。 Abs(number) number 参数可以是任意有效的数值表达式。如果 number 包含 Null,则返回 Null;如果是未初始化变量,则返回 0。
FormatPercent 函数 返回表达式,此表达式已被格式化为尾随有 % 符号的百分比(乘以 100 )。 FormatPercent(expression[,NumDigitsAfterD
FormatNumber 函数 返回表达式,此表达式已被格式化为数值。 FormatNumber( expression [,NumDigitsAfterDecimal [,Inc
我是一名优秀的程序员,十分优秀!