- iOS/Objective-C 元类和类别
- objective-c - -1001 错误,当 NSURLSession 通过 httpproxy 和/etc/hosts
- java - 使用网络类获取 url 地址
- ios - 推送通知中不播放声音
我正在实现一个简单的 VM,目前我正在使用运行时算法来计算各个程序对象地址作为基指针的偏移量。
我今天问了几个关于这个主题的问题,但我似乎无处可去。
我从第一个问题中学到了一些东西 - Object and struct member access and address offset calculation -我了解到现代处理器具有虚拟寻址功能,无需任何额外的算术周期即可计算内存偏移量。
从问题二 - Are address offsets resolved during compile time in C/C++? - 我了解到手动进行偏移时无法保证会发生这种情况。
现在应该很清楚,我想要实现的是利用硬件的虚拟内存寻址功能并从运行时卸载这些功能。
我正在使用 GCC,至于平台 - 我正在 Windows 中的 x86 上进行开发,但由于它是一个虚拟机,我希望它能在 GCC 支持的所有平台上高效运行。
欢迎提供有关该主题的任何信息,我们将不胜感激。
提前致谢!
编辑:关于我的程序代码生成的一些概述——在设计阶段,程序被构建为树状层次结构,然后递归地序列化到一个连续的内存块中,同时索引对象并计算它们从开始处的偏移量程序内存块。
编辑 2:这是虚拟机的一些伪代码:
switch *instruction
case 1: call_fn1(*(instruction+1)); instruction += (1+sizeof(parameter1)); break;
case 2: call_fn2(*(instruction+1), *(instruction+1+sizeof(parameter1));
instruction += (1+sizeof(parameter1)+sizeof(parameter2); break;
case 3: instruction += *(instruction+1); break;
情况 1 是一个接受一个参数的函数,该参数紧跟在指令之后,因此它作为指令的 1 个字节的偏移量传递。指令指针递增1+第一个参数的大小以找到下一条指令。
情况 2 是一个带有两个参数的函数,与之前相同,第一个参数作为 1 字节偏移量传递,第二个参数作为 1 字节偏移量加上第一个参数的大小传递。然后指令指针增加指令的大小加上两个参数的大小。
Case 3 是一个 goto 语句,指令指针增加了一个紧跟在 goto 指令之后的偏移量。
编辑 3:据我了解,操作系统将为每个进程提供其自己专用的虚拟内存寻址空间。如果是这样,这是否意味着第一个地址总是......好吧,零,所以内存块第一个字节的偏移量实际上就是这个元素的地址?如果内存地址专用于每个进程,并且我知道我的程序内存块的偏移量以及每个程序对象距内存块第一个字节的偏移量,那么对象地址是否在编译时解析?
问题是这些偏移量在 C 代码编译期间不可用,它们在“编译”阶段和转换为字节码时已知。这是否意味着没有办法为“免费”进行对象内存地址计算?
例如,这在 Java 中是如何完成的,其中只有虚拟机被编译为机器代码,这是否意味着对象地址的计算会因为运行时算法而导致性能下降?
最佳答案
这里试图阐明链接的问题和答案如何适用于这种情况。
第一个问题的答案混合了两个不同的东西,第一个是 X86 指令中的寻址模式,第二个是虚拟地址到物理地址的映射。第一个是由编译器完成的,第二个是(通常)由操作系统设置的。在您的情况下,您应该只担心第一个。
X86 汇编中的指令在如何访问内存地址方面具有很大的灵 active 。读取或写入内存的指令具有根据以下公式计算的地址:
segment + base + index * size + offset
地址的段部分几乎总是默认的 DS
段,通常可以忽略。 base
部分由通用寄存器之一或堆栈指针给出。 index
部分由通用寄存器之一给出,大小为 1、2、4 或 8。最后,偏移量是嵌入在指令中的常量值。这些组件中的每一个都是可选的,但显然至少必须给出一个。
这种寻址能力是在没有明确算术指令的情况下谈论计算地址时通常的意思。其中一位评论者提到了一条特殊指令:LEA
,它执行地址计算,但不是读取或写入内存,而是将计算出的地址存储在寄存器中。
对于问题中包含的代码,编译器很可能会使用这些寻址模式来避免显式算术指令。
例如,instruction
变量的当前值可以保存在 ESI
寄存器中。此外,sizeof(parameter1)
和 sizeof(parameter2)
都是编译时常量。在标准的 X86 调用约定中,函数参数以相反的顺序被压入(因此第一个参数位于堆栈的顶部)因此汇编代码可能看起来像
case1:
PUSH [ESI+1]
CALL fn1
ADD ESP,4 ; drop arguments from stack
ADD ESI,5
JMP end_switch
case2:
PUSH [ESI+5]
PUSH [ESI+1]
CALL fn2
ADD ESP,8 ; drop arguments from stack
ADD ESI,9
JMP end_swtich
case3:
MOV ESI,[ESI+1]
JMP end_switch
end_switch:
这是假设两个参数的大小都是 4 个字节。当然,实际代码取决于编译器,只要您要求进行某种程度的优化,编译器就会输出相当高效的代码是合理的。
关于c++ - 如何在 C/C++ 中从运行时卸载内存偏移量计算?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11494379/
好的,所以我想从批处理文件运行我的整个工作环境... 我想要实现什么...... 打开新的 powershell,打开我的 API 文件夹并从该文件夹运行 VS Code 编辑器(cd c:\xy;
我正在查看 Cocoa Controls 上的示例并下载了一些演示。我遇到的问题是一些例子,比如 BCTabBarController ,不会在我的设备上构建或启动。当我打开项目时,它看起来很正常,没
我刚刚开始学习 C 语言(擅长 Java 和 Python)。 当编写 C 程序(例如 hello world)时,我在 ubuntu cmd 行上使用 gcc hello.c -o hello 编译
我在 php 脚本从 cron 开始运行到超时后注意到了这个问题,但是当它从命令行手动运行时这不是问题。 (对于 CLI,PHP 默认的 max_execution_time 是 0) 所以我尝试运行
我可以使用命令行运行测试 > ./node_modules/.bin/wdio wdio.conf.js 但是如果我尝试从 IntelliJ 的运行/调试配置运行它,我会遇到各种不同的错误。 Fea
Error occurred during initialization of VM. Could not reserve enough space for object heap. Error: C
将 Anaconda 安装到 C:\ 后,我无法打开 jupyter 笔记本。无论是在带有 jupyter notebook 的 Anaconda Prompt 中还是在导航器中。我就是无法让它工作。
我遇到一个问题,如果我双击我的脚本 (.py),或者使用 IDLE 打开它,它将正确编译并运行。但是,如果我尝试在 Windows 命令行中运行脚本,请使用 C:\> "C:\Software_Dev
情况 我正在使用 mysql 数据库。查询从 phpmyadmin 和 postman 运行 但是当我从 android 发送请求时(它返回零行) 我已经记录了从 android 发送的电子邮件是正确
所以这个有点奇怪 - 为什么从 Java 运行 .exe 文件会给出不同的输出而不是直接运行 .exe。 当 java 在下面的行执行时,它会调用我构建的可与 3CX 电话系统配合使用的 .exe 文
这行代码 Environment.Is64BitProcess 当我的应用单独运行时评估为真。 但是当它在我的 Visual Studio 单元测试中运行时,相同的表达式的计算结果为 false。 我
关闭。这个问题是opinion-based .它目前不接受答案。 想要改进这个问题? 更新问题,以便 editing this post 可以用事实和引用来回答它. 关闭 8 年前。 Improve
我写了一个使用 libpq 连接到 PostgreSQL 数据库的演示。 我尝试通过包含将 C 文件连接到 PostgreSQL #include 在我将路径添加到系统变量 I:\Program F
如何从 Jenkins 运行 Android 模拟器来运行我的测试?当我在 Execiute Windows bath 命令中写入时,运行模拟器的命令: emulator -avd Tester 然后
我已经配置好东西,这样我就可以使用 ssl 登录和访问在 nginx 上运行的 errbit 我的问题是我不知道如何设置我的 Rails 应用程序的 errbit.rb 以便我可以运行测试 nginx
我编写了 flutter 应用程序,我通过 xcode 打开了 ios 部分并且应用程序正在运行,但是当我通过 flutter build ios 通过 vscode 运行应用程序时,我得到了这个错误
我有一个简短的 python 脚本,它使用日志记录模块和 configparser 模块。我在Win7下使用PyCharm 2.7.1和Python 3.3。 当我使用 PyCharm 运行我的脚本时
我在这里遇到了一些难题。 我的开发箱是 64 位的,windows 7。我所有的项目都编译为“任何 CPU”。该项目引用了 64 位版本的第 3 方软件 当我运行不使用任何 Web 引用的单元测试时,
当我注意到以下问题时,我正在做一些 C++ 练习。给定的代码将不会在 Visual Studio 2013 或 Qt Creator 5.4.1 中运行/编译 报错: invalid types 'd
假设我有一个 easteregg.py 文件: from airflow import DAG from dateutil import parser from datetime import tim
我是一名优秀的程序员,十分优秀!