我正在学习汇编 NASM 并尝试编写 LFSR 代码并在 C 程序上调用它以评估执行时间差异,但未能找出我的代码的问题。
我的 LFSR C 版本工作得很好,定义如下:
int lfsr(){
int cont = 0;
uint32_t start_state = SEED;
uint32_t lfsr = start_state;
uint32_t bit;
while (cont != 16777216) {
bit = ((lfsr >> 1) ^ (lfsr >> 5) ^ (lfsr >> 7) ^ (lfsr >> 13)) & 1;
lfsr = (lfsr >> 1) | (bit << 23);
lfsr_nums[cont] = lfsr;
cont++;
}
return cont;
}
我的 NASM x86 基于 C 版本,它以与 C 代码相同的方式生成数字。它应该将指向数组的指针作为参数,并返回(作为引用)与创建的数字相同的数组,并返回(作为值)数字的数量。LFSR 逻辑工作得很好,我检查了创建的数字,但代码仍然给我一个 SegFault Core Dump 错误。
使用 gdb 的消息是错误在执行过程中。当我尝试调试我的代码时,我发现错误出现在 中mov dword [esi + 4 * eax], ebx,如果我将其注释掉,则代码不会输出段错误。
section .text
global lfsr_nasm
lfsr_nasm:
push dword ebx;
mov esi, edi ; vec
mov eax, 0 ;Cont = 0
mov ebx, 0x1313 ; lfst = start_state = seed
do:
mov ecx, ebx ; ecx = lfst
shr ecx, 1 ; lfsr >> 1
mov edx, ebx ; edx = lfst
shr edx, 5; lfst >> 5
xor ecx, edx ; lfst >> 1 ^ lfsr >> 5
mov edx, ebx ; edx = lfsr
shr edx, 7 ; edx = lfst >> 7
xor ecx, edx; lfst >> 1 ^ lfsr >> 5 ^ lfsr >> 7
mov edx, ebx ; edx = lfsr
shr edx, 13 ; edx = lfst >> 13
xor ecx, edx; lfst >> 1 ^ lfsr >> 5 ^ lfsr >> 7 ^ lfsr >> 13
and ecx, 1 ;ecx = bit
shr ebx, 1 ;lfsr >> 1
shl ecx, 23 ; bit << 23
or ebx, ecx ; lfsr = (lfsr >> 1) | (bit << 23);
mov dword [esi + 4 * eax], ebx
inc eax ; cont++
cmp eax, 16777216; cont != 16777216
jne do ;
pop dword ebx;
ret
我在 C 中进行调用并声明我的向量和 NASM 函数的方式:
extern int lfsr_nasm (uint32_t *vec);
uint32_t lfsr_nums[16777216];
int main(int argc, char *argv[]){
int cont;
cont = lfsr_nasm(lfsr_nums);
for(int i = 0; i < 16777216; i++){
printf("%d ", lfsr_nums[i]);
}
}
我相信向量对于 NASM 或 C 来说太大了,也许程序正试图访问坏内存,但我找不到任何东西来证实我认为既不能解决问题。已经尝试过mallocand calloc。