【发布时间】:2021-05-16 02:23:22
【问题描述】:
我正在编写一个在程序集和 C++ 之间具有共享状态的程序。我在程序集文件中声明了一个全局数组,并在 C++ 中的函数中访问了该数组。当我从 C++ 中调用该函数时,没有问题,但随后我从程序集中调用相同的函数,我得到了分段错误。我相信我在函数调用中保留了正确的寄存器。
奇怪的是,当我将 C++ 中的指针类型更改为 uint64_t 指针时,它会正确输出值,但在将其转换为 uint64_t 后再次出现分段错误。
在下面的代码中,不断给我错误的数组是 currentCPUState。
//CPU.cpp
extern uint64_t currentCPUState[6];
extern "C" {
void initInternalState(void* instructions, int indexSize);
void printCPUState();
}
void printCPUState() {
uint64_t b = currentCPUState[0];
printf("%d\n", b); //this line DOESNT crash ???
std::cout << b << "\n"; //this line crashes
//omitted some code for the sake of brevity
std::cout << "\n";
}
CPU::CPU() {
//set initial cpu state
currentCPUState[AF] = 0;
currentCPUState[BC] = 0;
currentCPUState[DE] = 0;
currentCPUState[HL] = 0;
currentCPUState[SP] = 0;
currentCPUState[PC] = 0;
printCPUState(); //this has no issues
initInternalState(instructions, sizeof(void*));
}
//cpu.s
.section .data
.balign 8
instructionArr:
.space 8 * 1024, 0
//stores values of registers
//used for transitioning between C and ASM
//uint64_t currentCPUState[6]
.global currentCPUState
currentCPUState:
.quad 0, 0, 0, 0, 0, 0
.section .text
.global initInternalState
initInternalState:
push %rdi
push %rsi
mov %rcx, %rdi
mov %rdx, %rsi
push %R12
push %R13
push %R14
push %R15
call initGBCpu
pop %R15
pop %R14
pop %R13
pop %R12
pop %rsi
pop %rdi
ret
//omitted unimportant code
//initGBCpu(rdi: void* instructions, rsi:int size)
//function initializes the array of opcodes
initGBCpu:
pushq %rdx
//move each instruction into the array in proper order
//also fill the instructionArr
leaq instructionArr(%rip), %rdx
addop inst0x00
addop inst0x01
addop inst0x02
addop inst0x03
addop inst0x04
call loadCPUState
call inst0x04 //inc BC
call saveCPUState
call printCPUState //CRASHES HERE
popq %rdx
ret
其他细节: 操作系统:Windows 64 位 编译器 (MinGW64-w) 架构:x64
任何见解将不胜感激
编辑: addop 是一个宏:
//adds an opcode to the array of functions
.macro addop lbl
leaq \lbl (%rip), %rcx
mov %rcx, 0(%rdi)
mov %rcx, 0(%rdx)
add %rsi, %rdi
add %rsi, %rdx
.endm
【问题讨论】:
-
什么是
addop? -
addop 只是一个将元素添加到函数指针数组的宏。它只改变 RDI 和 RDX。