INC 操作码编译到错误的地址
INC opcode compiles to wrong address
我正在编译以下代码,但它没有按预期工作。
有人可以解释为什么以下代码不起作用以及如何纠正它吗?
DWORD data_location = 0x0100579C;
DWORD ret = 0x1002FFA;
void __declspec(naked) inc()
{
// The following is what I'm trying to accomplish which works
*(DWORD*)data_location = *(DWORD*)data_location + 1;
__asm
{
inc [data_location] //Should compile as FF 05 9C570001, instead compiles to the address containing the pointer to data_location
// inc data_location also compiles to the same thing above
jmp [ret]
}
}
[data_location]
与MASM语法中的data_location
相同。 方括号是可选的,而不是从静态存储中取消引用指针所需的额外间接级别。
请记住,在 C 中,data_location
会给你内存中的值,然后你的 C 会取消引用它。 但是内联 asm 使用 asm 语法。
如果希望它与硬编码到指令中的地址组合在一起,则需要使地址成为预处理器常量,而不仅仅是静态存储中的DWORD
变量。
#define data_location 0x0100579C
#define ret_addr 0x1002FFA
void __declspec(naked) inc()
{
//++*(DWORD*)data_location;
//((void (*)(void))ret)();
__asm
{
add dword ptr ds:[data_location], 1
// add dword ptr ds:[0x0100579C], 1 // after C preprocessor
mov eax, ret_addr
jmp eax
}
}
显然,为了使MASM/MSVC将[0x12345]
视为记忆操作数而不是即时操作数,需要ds:
。 但它也有在机器代码中实际发出冗余ds
前缀字节的缺点。
显然,您可以通过实际使用++*(DWORD*)data_location;
并让编译器内联add
或inc
指令来提高效率。 强制调用方实际调用此存根函数只会减慢您的速度。
add [mem], immediate
仅为 2 uops,而英特尔 CPU 上的内存目标inc
为 3 uops。 它只需要 1 个额外的代码大小字节。
jmp [ret]
DWORD ret = ...;
会起作用,但这是一个不幸的选择。 您实际上不需要从静态存储加载目标地址。 理想情况下,您会jmp 0x1002FFA
并让汇编程序计算到该绝对目标的相对偏移量。 但不幸的是,MASM 语法和/或 Windows.obj
文件不支持这一点。
如果您可以使用 tmp 寄存器,则将地址的 -立即mov
到寄存器中,避免需要任何静态数据,从而可能允许前端更快地整理分支错误预测。 不过,它仍然是一个间接分支。
此外,如果您实际call
此函数,请记住,调用方将推送您留在堆栈上的返回地址,因此这就像尾调用一样。
事实上,如果你只是在void
函数的末尾进行没有参数的普通函数调用,你可以让编译器为你发出一个jmp
。
如果我理解正确的话,你想要一些类似的东西
DWORD data_location = 0x0100579C;
DWORD ret = 0x1002FFA;
void __declspec(naked) inc()
{
__asm
{
mov eax, [data_location]
inc dword ptr [eax]
jmp [ret]
}
}
- 为什么我在leetcode上收到AddressSanitizer:地址0x602000000058上的堆缓冲区溢出错误
- 地址的奇怪错误
- 为什么我得到以下代码地址清理器:未知地址错误的SEGV
- 运行时错误:引用绑定到类型"int"的未对齐地址0xbebebebebebebec6,这需要 4 个字节对齐 (stl_vector.h)
- 我有一个线程 1:EXC_BAD_ACCESS(代码 = 1,地址 = 0x8)错误.我认为这是由于内存管理不好.我可以
- Assimp 库错误:获取打包成员的地址
- 运行时错误地址清理器:LEETCODE 中的致命信号
- 瓦尔格林德错误 - 地址0x0不是堆叠的 malloc'd 或自由的
- 获取未知分段错误"(地址)在 std::__cxx11::basic_string<char, std::char_traits<char>,..., std::分配器<cha
- 来自简单循环的 OpenAcc 错误:内核执行期间的非法地址
- 带有 NORM 的 ZeroMQ - 地址已在使用 错误被抛出在第二个 .bind() 上 - 为什么?
- 重载新返回错误的地址
- 线程 1:xcode 中出现EXC_BAD_ACCESS(代码 = 1,地址 = 0x0)错误
- cv::Mat中的地址错误
- 尝试使用pthreads访问共享数据数组时,出现“无法访问内存地址”错误
- Windbus示例应用程序无法启动(无法解析服务器地址错误)
- 分配OpenCL缓冲区时内存地址错误
- 未定义的引用,但(动态)库被链接.(可能是坏的重定位地址错误)
- 圆括号成员函数地址错误
- ZeroMQ:重新绑定套接字时使用地址错误