在 c++ 内部定义变量内联组装

发布于 2024-08-04 09:13:16 字数 161 浏览 4 评论 0原文

假设我们有以下 C++ 代码:

int var1;

__asm {
    mov var1, 2;
}

现在,我想知道的是,如果我不想在 __asm 指令之外定义 var1,我需要做什么才能将其放入其中。有可能吗?

谢谢

Let's say we have the following c++ code:

int var1;

__asm {
    mov var1, 2;
}

Now, what I'd like to know is if I didn't want to define var1 outside the __asm directive, what would I have to do to put it inside it. Is it even possible?

Thanks

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

dawn曙光 2024-08-11 09:13:16

为此,您需要使用 _declspec(naked) 创建一个“裸”方法,并自己编写通常由编译器创建的序言和结尾。

prolog 的目的是:

  • 设置 EBP 和 ESP
  • 在堆栈上为局部变量保留空间
  • 保存应在函数体中修改的寄存器

Epilog 必须:

  • 恢复保存的寄存器值
  • 清理局部变量的保留空间

下面是一个标准的序言

push        ebp                ; Save ebp
mov         ebp, esp           ; Set stack frame pointer
sub         esp, localbytes    ; Allocate space for locals
push        <registers>        ; Save registers

和一个标准的尾声:

pop         <registers>   ; Restore registers
mov         esp, ebp      ; Restore stack pointer
pop         ebp           ; Restore ebp
ret                       ; Return from function

然后,您的局部变量将从 (ebp - 4) 开始,向下到达 (ebp - 4 - localbytes)。函数参数将从 (ebp + 8) 开始并向上。

To do that, you'll need to create a "naked" method with _declspec(naked) and to write yourself the prolog and the epilog that are normally created by the compiler.

The aim of a prolog is to:

  • set up EBP and ESP
  • reserve space on stack for local variables
  • save registers that should be modified in the body of the function

An epilog has to:

  • restore the saved register values
  • clean up the reserved space for local variables

Here is a standard prolog

push        ebp                ; Save ebp
mov         ebp, esp           ; Set stack frame pointer
sub         esp, localbytes    ; Allocate space for locals
push        <registers>        ; Save registers

and a standard epilog:

pop         <registers>   ; Restore registers
mov         esp, ebp      ; Restore stack pointer
pop         ebp           ; Restore ebp
ret                       ; Return from function

Your local variables will then begin at (ebp - 4) and go downward to (ebp - 4 - localbytes). The function parameters will start at (ebp + 8) and go upward.

挽清梦 2024-08-11 09:13:16

在汇编程序中创建 C 变量是不可能的:C 编译器必须知道该变量(即它的类型和地址),这意味着它必须在 C 代码中声明。

可以做的是通过 C 中的 extern 声明访问汇编程序中定义的符号。但这对于具有自动存储持续时间的变量不起作用,因为它们没有固定地址,而是相对引用的到基指针。

如果您不想访问 asm 块之外的变量,可以使用堆栈来存储汇编程序本地数据。请记住,在离开 asm 块时,您必须将堆栈指针恢复到其先前的值,例如,

sub esp, 12       ; space for 3 asm-local 32bit vars
mov [esp-8], 42   ; set value of local var
[...]
push 0xdeadbeaf   ; use stack
[...]             ; !!! 42 resides now in [esp-12] !!!
add esp, 16       ; restore esp

如果您不希望在操作堆栈时更改局部变量的相对地址(即使用pushpop),您必须建立一个堆栈帧(即在ebp中保存堆栈的基址并相对于本地地址到这个值),如 cedrou 的回答中所述。

It' impossible to create a C variable in assembler: the C compiler has to know about the variable (ie its type and address), which means it has to be declared in the C code.

What can be done is accessing symbols defined in assembler via extern declarations in C. That won't work for variables with automatic storage duration, though, as these don't have a fixed address but are referenced relative to the base pointer.

If you don't want to access the variables outside of the asm block, you can use the stack for storing assembler-local data. Just keep in mind that you have to restore the stack pointer to its previous value when leaving the asm block, eg

sub esp, 12       ; space for 3 asm-local 32bit vars
mov [esp-8], 42   ; set value of local var
[...]
push 0xdeadbeaf   ; use stack
[...]             ; !!! 42 resides now in [esp-12] !!!
add esp, 16       ; restore esp

If you don't want the relative addresses of the local variables to change whenever you manipulate the stack (ie use push or pop), you have to establish a stack frame (ie save the base of the stack in ebp and address locals relative to this value) as described in cedrou's answer.

恍梦境° 2024-08-11 09:13:16

局部变量是通过 ESP 寄存器操作调用堆栈上的可用空间来分配和释放的,即:

__asm
{
    add esp, 4
    mov [esp], 2;
    ...
    sub esp, 4
}

通常,最好通过为调用函数建立一个“堆栈帧”来处理,然后访问局部变量(和函数参数) ) 使用帧内的偏移量,而不是直接使用 ESP 寄存器,即:

__asm
{
    push ebp
    mov ebp, esp
    add esp, 4
    ...
    mov [ebp-4], 2;
    ...
    mov esp, ebp
    pop ebp
}

Local variables are allocated and freed by manipulating the available space on the call stack via the ESP register, ie:

__asm
{
    add esp, 4
    mov [esp], 2;
    ...
    sub esp, 4
}

Generally, this is better handled by establishing a "stack frame" for the calling function instead, and then access local variables (and function parameters) using offsets within the frame, instead of using the ESP register directly, ie:

__asm
{
    push ebp
    mov ebp, esp
    add esp, 4
    ...
    mov [ebp-4], 2;
    ...
    mov esp, ebp
    pop ebp
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文