我想知道如何检索使用内联汇编调用我的函数的函数的地址.我的想法是将地址发送到调用我的函数将返回的位置并使用前面的指令(这是对调用我的函数的调用)检索调用我的函数的地址添加到给定的偏移量调用,到下一条指令的地址(调用我的函数将返回的地址).到目前为止,我能够做到这一点,但要获得我的地址.它非常简单,有效:
_asm
{
mov eax, [ebp+4]
mov returnTo,eax
}
long addressOfMine = (*((long*)(returnTo - sizeof(long)))) + returnTo)
Run Code Online (Sandbox Code Playgroud)
这检索我的地址就好了.(通过知道[ebp + 4]是我将返回的地址)
为了做同样的但是上面一步,我试图获得旧的ebp并做同样的事情.我在一个网站上看到[ebp + 0]是旧的ebp所以我试过了:
_asm
{
mov eax, [ebp]
mov ebx, [eax+4]
mov returnTo,ebx
}
long addressOfCaller = (*((long*)(returnTo - sizeof(long)))) + returnTo)
Run Code Online (Sandbox Code Playgroud)
但它不起作用.所以,我的假设是错误的,或者我做错了所以我想请求你的帮助.
我有一个带有xchg指令的自旋锁.C++函数接受要锁定的资源.
以下是代码
void SpinLock::lock( u32& resource )
{
__asm__ __volatile__
(
"mov ebx, %0\n\t"
"InUseLoop:\n\t"
"mov eax, 0x01\n\t" /* 1=In Use*/
"xchg eax, [ebx]\n\t"
"cmp eax, 0x01\n\t"
"je InUseLoop\n\t"
:"=r"(resource)
:"r"(resource)
:"eax","ebx"
);
}
void SpinLock::unlock(u32& resource )
{
__asm__ __volatile__
(
/* "mov DWORD PTR ds:[%0],0x00\n\t" */
"mov ebx, %0\n\t"
"mov DWORD PTR [ebx], 0x00\n\t"
:"=r"(resource)
:"r"(resource)
: "ebx"
);
}
Run Code Online (Sandbox Code Playgroud)
此代码在64位intel机器上使用 gcc 4.5.2 编译 -masm=intel.
在 objdump 用于上述功能产生以下组件.
0000000000490968 <_ZN8SpinLock4lockERj>:
490968: 55 push %rbp
490969: 48 89 …Run Code Online (Sandbox Code Playgroud) 我无法编译这个,我应该如何在Visual Studio中将[eax + 4]移动到y?
float x, y, z;
__asm
{
mov x, eax
mov y, [eax+4]
mov z, [eax+8]
}
Run Code Online (Sandbox Code Playgroud)
编辑:"错误1错误C2424:'+':'第二个操作数'中的表达式不正确"
我试图找到一个非常基本的C++内联x86-64汇编示例,类似于:
C/C++中的简单"Hello World"内联汇编语言程序
char msg[] = "Hello, world";
asm {
mov ax,4 // (I/O Func.)
mov bx,1 // (Output func)
lds cx, msg // (address of the string)
mov dx,6 // (lenght of the string)
int 0x21 // system call
}
Run Code Online (Sandbox Code Playgroud)
哪个适用于英特尔编译器.有人可以帮忙吗?
编辑关于操作系统我在Windows和Linux上有ICC - 让我们说Linux吧!
我正在尝试为某些win32 api函数编写一个trampoline挂钩,当我将JMP指令写入原始函数的开头时,我希望它跳转到codecave而不是调用函数.
OllyDBG中的原始函数start如下所示:
PUSH 14
MOV EAX, 12345678
...
Run Code Online (Sandbox Code Playgroud)
我将其修补为:
JMP 87654321
NOP
NOP
Run Code Online (Sandbox Code Playgroud)
以下功能的地址:
int HookFunc(int param)
{
DoStuff(param);
return ExecuteOriginal(param);
}
Run Code Online (Sandbox Code Playgroud)
ExceuteOriginal看起来像这样:
unsigned long address = AddressOfOriginalFunction + 7;
int ExceuteOriginal(int param)
{
__asm
{
PUSH 0x14
MOV EAX, 0x12345678
JMP address
}
}
Run Code Online (Sandbox Code Playgroud)
执行被覆盖的代码并在修补后的代码后立即跳转到原始函数.问题在于,由于它是一个函数,它会使堆栈陷入困境,因为调用者应该清理它并且函数而不是返回,跳转到另一个函数的代码.我猜这就是程序崩溃的原因.
有没有办法使用Visual C++编译器将汇编代码放在程序的代码部分而不是在函数内部?这样我就可以跳到那里,执行任何操作,然后返回,而不会有弄乱堆栈的风险.
我尝试asm("hlt");在win8 上做,但提示Windows错误窗口.
有什么方法可以让HLT继续运行一段时间吗?
请考虑以下代码
int a = 10;
int b = 2;
int c = 0;
int asmdivide(void);
int main(int argc, char* argv[])
{
c = a / b;
asmdivide();
return 0;
}
int asmdivide()
{
__asm
{
push dword ptr[a]
push dword ptr[b]
pop ecx
idiv ecx, dword ptr[a] //causes compile error
push ecx
pop dword ptr[c]
}
return c;
}
Run Code Online (Sandbox Code Playgroud)
为什么这idiv ecx, ds:dword ptr[a] //causes compile error行当编译器idiv eax,dword ptr ds:[1308004h]从这行`int b = 2 生成这条指令时导致编译错误;
输出的错误是
error C2414: …Run Code Online (Sandbox Code Playgroud) 为什么Visual Studio C++编译器默认情况下不会优化以下代码?
#include "ctime"
#include "iostream"
#define BIG_NUM 10000000000
int main() {
std::clock_t begin = clock();
for (unsigned long long i = 0; i < BIG_NUM; ++i) {
__asm
{
nop
}
}
std::clock_t end = clock();
std::cout << "time: " << double(end - begin) / CLOCKS_PER_SEC;
std::cin.get();
}
Run Code Online (Sandbox Code Playgroud)
如果没有_asm块,则操作时间始终为0,因为由于编译器优化,完全"跳过"循环.使用该_asm块只需几秒钟.
是否有任何编译器标志来优化内联汇编或由于某些不明原因而无法实现?
有人可以帮我加速我的Delphi函数在不使用二进制搜索的情况下在字节数组中查找值.
我把这个函数称为数千次,是否可以用汇编来优化它?
非常感谢.
function IndexOf(const List: TArray< Byte >; const Value: byte): integer;
var
I: integer;
begin
for I := Low( List ) to High( List ) do begin
if List[ I ] = Value then
Exit ( I );
end;
Result := -1;
end;
Run Code Online (Sandbox Code Playgroud)
数组的长度约为15项.
我正在学习如何__asm__ volatile在GCC中使用,并提出了一个问题。我想实现一个执行原子比较和交换并返回先前存储在目标中的值的函数。
为什么"=a"(expected)输出约束起作用,但是"=r"(expected)约束使编译器生成不起作用的代码?
情况1。
#include <inttypes.h>
#include <stdint.h>
#include <stdio.h>
uint64_t atomic_cas(uint64_t * destination, uint64_t expected, uint64_t value){
__asm__ volatile (
"lock cmpxchgq %3, %1":
"=a" (expected) :
"m" (*destination), "a" (expected), "r" (value) :
"memory"
);
return expected;
}
int main(void){
uint64_t v1 = 10;
uint64_t result = atomic_cas(&v1, 10, 5);
printf("%" PRIu64 "\n", result); //prints 10, the value before, OK
printf("%" PRIu64 "\n", v1); //prints 5, the new value, OK
}
Run Code Online (Sandbox Code Playgroud)
它按预期工作。现在考虑以下情况: …