为什么我的x86汇编代码会导致分段错误?

时间:2011-12-11 05:08:59

标签: c++ assembly x86 segmentation-fault

这又是一个功课。但请相信我,我已经尽力解决这个问题,现在我没有选择。

基本上我已经完成了将此功能从C转换为程序集的任务。这是一个更大问题的一部分。我不打算发布整个项目,因为我不想把我的项目强加给你们。基本上只是这一部分。对于那些好奇的人来说,该项目是采用BMP文件并顺时针旋转90度。

这是C函数:

void rotate_clock_helper (char* map, char *newmap, int mapsize, int width, int height) {
  int i, j;
  for(i = 0; i < width; i++){
    for(j = 0; j < height; j++){
      newmap[3*(((height)*(width-1-j))+(height-1-i))+0] = map[3*(width*(height-1-i)+j)+0];
      newmap[3*(((height)*(width-1-j))+(height-1-i))+1] = map[3*(width*(height-1-i)+j)+1];
      newmap[3*(((height)*(width-1-j))+(height-1-i))+2] = map[3*(width*(height-1-i)+j)+2];
    }
  }
}

这是我尝试在装配中重做它。注意,我不太关心效率。我只需要先完成一些事情。

extern printf

segment .data

segment .text

    global  rotate_clock_helper

rotate_clock_helper:        
    enter   4,0

    mov ecx,    0   ;i
    mov edx,    0   ;j

iloop:
    mov eax,    [ebp+20] ;width
    cmp eax,    ecx  ;while i < width keep looping
    je  done

jloop:
    mov eax,    [ebp-24] ;height
    cmp eax,    edx  ;while j < height keep looping
    je  resetJ

    ;; do operation here
    mov esi,    [ebp+08] ;map
    mov edi,    [ebp+12] ;newmap

    mov eax,    [ebp+20] ;width
    mov ebx,    [ebp+24] ;height

    sub eax,    1   ;width-1
    sub eax,    edx ;width-1-j
    imul    eax,    ebx ;(width-1-j)*height
    sub ebx,    1   ;height-1
    sub ebx,    ecx ;height-1-i
    add eax,    ebx ;(width-1-j)*height + (height-1-i)
    imul    eax,    3   ;3*eax
    mov [ebp-04], eax   ;saves this value to memory

    mov eax,    [ebp+20] ;width
    mov ebx,    [ebp+24] ;height

    sub ebx,    1   ;height - 1
    sub ebx,    ecx ;height-1-i
    imul    ebx,    eax ;width * (height-1-i)
    add ebx,    edx ;width * (height-1-i)+j
    imul    ebx,    3   ;ebx = 3 * ebx

    mov eax,    [ebp-04] ;self explanatory?
    ;; Now eax and ebx have the shift values
    add edi,    eax ;shift the edi value
    add esi,    ebx ;shift the esi value

    mov eax,    [esi]   ;move the value to eax
    mov [edi],  eax ;move the proper value into the newmap

    inc esi     ;esi + 1
    inc edi     ;edi + 1

    mov eax,    [esi]   ;same thing as before
    mov [edi],  eax ;same thing as before

    inc esi     ;esi + 1;
    inc edi     ;edi + 1

    mov eax,    [esi]   ;repeat again
    mov [edi], eax  ;repeat

    ;; operations end
    inc edx     ;j++

    jmp jloop

resetJ:
    mov edx,    0   ;reset j <- 0
    inc ecx     ;i++
    jmp iloop       

done:
    leave
ret

任何人都可以帮我弄清楚为什么会出现这种分段错误吗?

1 个答案:

答案 0 :(得分:3)

我很确定这一行:

jloop:
    mov eax,    [ebp-24] ;height

应该是:

jloop:
    mov eax,    [ebp+24] ;height

实际上,jloop的上限是使用堆栈中其他位置的随机值,而不是height