Сортировка выбора в сборке x86

#c #sorting #assembly #x86 #selection

#c #сортировка #сборка #x86 #выбор

Вопрос:

Это домашнее задание, если кому-то интересно.

Задача состоит в том, чтобы программа на C создала 2D-массив и передала этот массив в сборку, в которой он должен быть отсортирован с помощью сортировки по выбору.

Ошибка, с которой я сталкиваюсь при попытке ее запуска, — ошибка сегментации. Я пытался поместить

 push tesst
push sout
call printf
  

чтобы распечатать «test» в окне терминала, но я не мог понять, откуда он берется. Я также попытался поместить его сразу после «введите 0,0», и я все еще не получил распечатку теста. Итак, у меня совершенно нет идей относительно того, где я получаю ошибку сегментации.

Любая помощь была бы очень признательна. 🙁 Ожидается завтра вечером, и я застрял на этом пару дней. Кто-нибудь, пожалуйста, пролей немного света

-Крис

Коды будут ниже

моя программа на 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 Stringsn");
  for(i = 0; i < 3; i  ){
    for(j = 0; j < 5; j  ){
      printf("%c", hi[i][j]);
    }
    printf("n");
  }
  printf("It Got Heren");
  ssort((char*)hi, 5, 3);
  printf("Sortedn");
  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:

Отладка в стиле печати подходит в ситуациях, когда больше ничего не доступно, но ничто не сравнится с тем, чтобы запутаться в отладчике исходного уровня.

Шаг 1. Вероятно, самый простой способ — сначала вывести вызов в сборку и запустить его, чтобы убедиться, что проблема не в вашем коде C.

Шаг 2. Затем верните вызов и загрузите его в gdb или в ваш любимый отладчик исходного кода. Установите точку останова в первой инструкции ассемблера. Когда он прерывается, проверьте стек, чтобы убедиться, что это то, что вы ожидаете.

Шаг 3: затем выполните один шаг по сборке, пока не найдете свою проблему.

Это будет лучшим способом для вас научиться, а также быстро найти и устранить вашу проблему.


Я скажу вам одну вещь, которую я вижу как потенциальную проблему. Сразу после iloop метки у вас есть push esi . Я не вижу pop (или другого esp модифицирующего оператора) нигде в вашем коде, и, что еще хуже, это push происходит в цикле.

Если вы попытаетесь вернуться из функции с указателем стека, отличным от того, что было при вводе, вас ждет мир боли. Возможно, я просто что-то пропустил, но я бы начал с поиска там.

Комментарии:

1. Благодаря проблеме в compare () я даже не знал о gdb до сих пор. Я говорю, что ведьма-ремесло! : P большое спасибо

2. Отмечено и исправлено. Еще раз спасибо