【发布时间】:2020-05-09 15:28:02
【问题描述】:
我正在尝试从具有四个参数的 C++ 代码调用 x64 汇编函数,并且汇编函数每次都将第一个参数重置为零。请在下面找到代码 sn-p。
C++ 代码:test.cpp
#include <iostream>
extern "C" int IntegerShift_(unsigned int a, unsigned int* a_shl, unsigned int* a_shr, unsigned int count);
int main(int argc, char const *argv[])
{
unsigned int a = 3119, count = 6, a_shl, a_shr;
std::cout << "a value before calling " << a << std::endl;
IntegerShift_(a, &a_shl, &a_shr, count);
std::cout << "a value after calling " << a << std::endl;
return 0;
}
x64 汇编代码:test.asm
section .data
section .bss
section .text
global IntegerShift_
IntegerShift_:
;prologue
push rbp
mov rbp, rsp
mov rax, rdi
shl rax, cl
mov [rsi], rax
mov rax, rdi
shr rax, cl
mov [rdx], rax
xor rax,rax
;epilogue
mov rbp, rsp
pop rbp
ret
我正在以下环境中工作。
操作系统 - Ubuntu 18.04 64 位
汇编程序 - nasm (2.13.02)
C++ 编译器 - g++ ( 7.4.0)
处理器 - Intel® Pentium(R) CPU G3240 @ 3.10GHz × 2
我正在编译我的代码,如下所示
$ nasm -f elf64 -g -F dwarf test.asm
$ g++ -g -o test test.cpp test.o
$ ./test
$ a value before calling 3119
$ a value after calling 0
但是如果我从汇编函数中注释掉mov [rdx], rax 行,它不会重置variable a 的值。我是 x64 汇编编程的新手,我找不到 rdx 寄存器和变量 a 之间的关系。
【问题讨论】:
-
这没有多大意义。
a是按值传递的。尝试将其设为const看看会发生什么。 -
@Resurrection 使
a不断解决了这个问题,但你能解释一下原因吗?如何将a的值更改为另一个值并再次调用汇编函数。 -
@Resurrection 将
a设为常量的建议只是让编译器将其用作对cout.operator<<(int)的调用的立即数,而不是将其存储/重新加载到您的错误asm 可以破坏的堆栈中它。这不是对 asm 错误的修复,只是有明显的效果。 (如果您知道编译器如何在反优化调试模式下工作,则很明显:P)