选择在x86程序集上排序

时间:2011-11-04 04:58:51

标签: c sorting assembly x86 selection

如果有人好奇的话,这是一个功课。

任务是让一个C程序创建一个2D数组并将该数组传递给程序集,它应该使用选择排序进行排序。

我在尝试运行它时遇到的错误是分段错误。我试过把

push tesst
push sout
call printf

在终端窗口打印出“test”,但我无法弄清楚它来自哪里。我也试过在“输入0,0”之后把它放好,我仍然没有打印出测试版。所以我完全没有关于我在哪里得到分段错误的想法。

非常感谢任何帮助。 :(明天晚上到期,我已经被困在这几天了。有人请光一点

-Chris

代码将在

之下

我的c程序

#include <stdio.h>

int ssort(char * hi[], int x, int y);

int main(){

  int i, j;


  char hi[3][5] = {"Yoshi", "Annie", "Chris"};

  printf("Display Unsorted Strings\n");
  for(i = 0; i < 3; i++){
    for(j = 0; j < 5; j++){
      printf("%c", hi[i][j]);
    }
    printf("\n");
  }
  printf("It Got Here\n");
  ssort((char*)hi, 5, 3);
  printf("Sorted\n");
  for(i = 0; i < 3; i++){
    for(j = 0; j < 5; j++){
      printf("%c", hi[i][j]);
    }
    printf("\n");
  }
}

我的汇编代码

extern    printf

segment   .data

tesst db  't','e','s','t',0
sout  db  "%s", 10, 0

segment   .text

  global  ssort

ssort:    
  enter   0,0

;;; for(i = 0; i < namecount; i++){
;;;   for(j = 1; j < namecount; j++){
;;;       if(array[i] < array[j])
;;;           do nothing
;;;       else
;;;           swap
;;;   }
;;; }


  mov esi,    [ebp+8] 
  mov edi,    esi
  add edi,    [ebp+8]
  mov ecx,    0   ;i
  mov edx,    0
  add edx,    1   ;j
  ;; [ebp+16] = namecount

iloop:
  push    esi
  cmp ecx,    [ebp+16]
  je  done_sorting
jloop:
  cmp edx,    [ebp+16]
  je  j_done

;;; compare here now
compare:
  mov al, [esi]
  mov bl, [edi]
  cmp al, bl
  jg  alisbigger
  jl  blisbigger
  inc esi
  inc edi
  jmp compare
alisbigger:   
  jmp swap
blisbigger:   
  jmp done

swap:
  mov ebx,    0
  mov ebx,    [ebp+12]
swap_loop:
  dec ebx

  mov al, [esi]
  mov bl, [edi]
  mov [esi],  bl
  mov [edi],  al

  inc esi
  inc edi

  cmp ebx,    0
  je  done
  jmp swap_loop

done:
  inc edx
  jmp jloop

j_done:
  add ecx, 1
  add esi, [ebp+12]
  mov edx, 1
  jmp iloop   


done_sorting:
  leave
  ret

1 个答案:

答案 0 :(得分:1)

在没有其他可用的情况下打印样式调试是可以的,但 nothing 在源代码级调试器中击败和弄脏。

第1步:可能最简单的方法是首先将调用取出到程序集并运行它,以确保它不是导致问题的C代码。

第2步:然后,将回调放入并将其加载到gdb或您喜欢的源级调试器中。在第一个汇编指令上设置断点。当它破裂时,检查堆栈以确保它符合您的期望。

第3步:然后单步完成装配,直到找到问题为止。

这将是您学习,快速找到并解决问题的最佳方式。


我会告诉你一个我认为是一个潜在的问题。在iloop标签之后,您有push esi。我在代码中看不到pop(或其他esp - 修改语句) where ,更糟糕的是,push正在循环中发生

如果您尝试从堆栈指针不同的函数返回到您输入时的状态,那么您将陷入痛苦的世界。我可能只是错过了一些东西,但我会先从那里开始。