- iOS/Objective-C 元类和类别
- objective-c - -1001 错误,当 NSURLSession 通过 httpproxy 和/etc/hosts
- java - 使用网络类获取 url 地址
- ios - 推送通知中不播放声音
我正在构建其中一个项目,我正在查看生成的列表文件。(目标:x86-64)我的代码如下所示:
int func_1(var1,var2){
asm_inline_(
)
func_2(var1,var2);
return_1;
}
void func_2(var_1,var_2){
asm __inline__(
)
func_3();
}
/**** Jump to kernel ---> System call stub in assembly. This func in .S file***/
void func_3(){
}
当我看到汇编代码时,我发现在调用 func_2 和 func_3 时使用了“jmp”指令而不是“call-return”对。我确信这是编译器优化之一,我还没有探索如何禁用它。 (海湾合作委员会) 当我向 func_2 和 func_3 添加一些可变变量并递增它们时,“jmp”被“call-ret”对替换。 我很困惑地看到这种行为,因为这些变量是无用的,它们没有任何作用。 有人可以解释这种行为吗?
谢谢
最佳答案
如果代码跳转到另一个函数的开始而不是调用它,当跳转到的函数返回时,它将返回到调用外部函数的地方,忽略任何更多该点之后的第一个函数。假设行为是正确的(无论如何,第一个函数在那之后对执行没有任何贡献),这是一种优化,因为它减少了一个级别的指令和堆栈操作的数量。
在给定的示例中,行为是正确的;没有要弹出的本地堆栈,也没有要返回的值,因此调用后不需要运行代码。 (return_1
,假设它不是某个东西的宏,是一个纯表达式,因此无论它的值如何,它什么都不做。)所以当它没有更多的东西时,没有理由为将来保留堆栈框架为事件做贡献。
如果您将 volatile 变量添加到函数体中,您不仅仅是在添加编译器可以分析其流程的变量 - 您是在添加您已明确告诉编译器可以访问的槽 在它可以预测的正常控制流之外。 volatile
限定符警告编译器,即使变量没有明显的转义方式,外部的某些东西也有办法获取它们的地址并随时写入它。所以它不能减少它们的生命周期,因为有人告诉函数外的代码可能仍会尝试写入该堆栈空间;显然,这意味着堆栈框架需要在其声明的整个生命周期内继续存在。
关于编译器优化 call-ret vs jmp,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26615246/
有什么区别: 1) !ret 2) ret != 0 ? if (ret != 0 || stack[fd] == NULL || stack[fd][0] == '\0') { if (!ret
我正在使用 java 客户端 (jrets) 来查询 RETS 服务器。此 rets 服务器不支持 OFFSET 功能。 服务器管理员告诉我使用 MODIFIED 字段作为翻阅记录的一种方式。但是,我
我想从 RETS 服务器下载所有属性(property) list ,包括所有照片 URL。我正在使用 DMQL2 和 PHRETS 库。属性和照片对象存储在 RETS 服务器的不同表中。 要获取所有
各位, 我将使用 RETS 进行真实项目。我有一份文件,说明我的经理实际上在寻找什么。但我真的不知道如何开始使用 RETS MLS,因为它有很多这样的文档。 通过一些研发,我几乎没有想出任何有值(va
我正在尝试在 Microsoft visual studio 2013 on C++ 上编译一个为 linux 编写的程序(是 C 和 C++ 的混合体 (#include .h),我将全部转换为 C
当我尝试像这样编写自己的decay_t时: #include template struct auto_decay { auto operator () () noexcept {
我经常看到通过测试小于零而不是显式定义来检查 POSIX 函数错误的代码,通常唯一的错误代码使用 -1。也就是 ret = function(); if (ret < 0) { ... } 对
考虑以下空 C 程序(标准保证编译器执行隐式 return 0): int main(int argc, char* argv[]) {} 您可以将任何逻辑添加到此函数中来操作 argc 和 argv
我在 ubuntu 12.04 和 auctex 11.86 上运行 emacs 23.3.1。每当我去编译 latex 文档(使用 C-c C-c)时,如果没有错误,一切都编译得很好。但是,如果有任
我有 RETS 元数据文件,我想将其转换为数据库模式,这样我就可以查询我的数据库而不是 RETS 服务器。 有谁知道可以使用 xml 并将其转换为数据库模式的工具?或者可能是数据库模式本身? 一切都包
由于 ret 指令是一个间接调用,x86 上的 ret 指令会停止流水线,还是以某种方式优化为更直接的调用? 最佳答案 根据英特尔优化引用手册,分支预测单元包含一个 Return Stack Buff
我有以下头文件: #include #include #include #include #include #include /** **/ // size: 1B typedef en
我目前正在开发一个网站并从 RETS(房地产交易标准)API 中提取列表。我的一切工作正常,但我的问题是在尝试深入挖掘查询时出现的。作为引用,我正在使用 Node RETS Client但我不确定它与
if(isset($_POST['update'])) { $rets_login_url = $Fetch['rets_url']; $rets_username = $Fetch['rets_us
我有这个函数,它主要由内联汇编码成。 long *toarrayl(int members, ...){ __asm{ push esp mov eax, me
int suma(int* array, int len) { asm(" xor %eax, %eax # resultado = 0 \n"
我对汇编很陌生,我不明白在 proc 结束时你用 ret 写一个数字的确切含义是什么。陈述。 像这样: Function Proc push ax cx . ...body... . pop cx a
我正在尝试使用 PHRETS 从 rets 服务器在 WordPress 中添加帖子。不幸的是,正在添加重复的帖子。我已使用 WP 查询使用元键和值检查现有帖子。当我尝试添加 10 或 50 个帖子时
我有以下程序: SECTION .text main: mov ebx, 10 mov ecx, 50 repeat: inc ebx loop repeat
假设我正在 x86 汇编中编写一个例程,例如“add”,它将两个作为参数传递的数字相加。 在大多数情况下,这是一个非常简单的方法: push ebp mov ebp, esp mov eax, [eb
我是一名优秀的程序员,十分优秀!