Помощь с домашним заданием - вопрос выбора ассемблера GNU - PullRequest
1 голос
/ 12 февраля 2011

Мне нужно создать программу в ассемблере, которая принимает ввод пользователя как максимальный размер массива, а затем позволяет пользователю создать массив этого размера.Я должен буферизовать это значение максимум до 1000 элементов массива (все целые числа). Затем мне нужно выполнить сортировку выбора по массиву и вывести.сайт.

    .section .data

   array:
      .byte  89, 10, 67, 1, 4, 27, 12, 34, 86, 3

   array_end:
      .equ ARRAY_SIZE, array_end - array

   array_fmt:
      .asciz "  %d"

   usort_str:
      .asciz "unsorted array:"

   sort_str:
      .asciz "sorted array:"

   newline:
      .asciz "\n"


.section .text
.globl main

main:
      pushl $usort_str
      call  puts
      addl  $4, %esp

      pushl $ARRAY_SIZE
      pushl $array
      pushl $array_fmt
      call  print_array10
      addl  $12, %esp

      pushl $ARRAY_SIZE
      pushl $array
      call  sort_routine20

# Adjust the stack pointer
      addl  $8, %esp

      pushl $sort_str
      call  puts
      addl  $4, %esp

      pushl $ARRAY_SIZE
      pushl $array
      pushl $array_fmt
      call  print_array10
      addl  $12, %esp
      jmp   _exit



print_array10:
      pushl %ebp
      movl  %esp, %ebp
      subl  $4, %esp
      movl  8(%ebp), %edx
      movl  12(%ebp), %ebx
      movl  16(%ebp), %ecx

      movl  $0, %esi

push_loop:
      movl  %ecx, -4(%ebp)  
      movl  8(%ebp), %edx
      xorl  %eax, %eax
      movb  (%ebx, %esi, 1), %al
      pushl %eax
      pushl %edx

      call  printf
      addl  $8, %esp
      movl  -4(%ebp), %ecx
      incl  %esi
      loop  push_loop

      pushl $newline
      call  printf
      addl  $4, %esp
      movl  %ebp, %esp
      popl  %ebp
      ret

sort_routine20:
      pushl %ebp
      movl  %esp, %ebp

# Allocate a word of space in stack
      subl  $4, %esp

# Get the address of the array
      movl  8(%ebp), %ebx

# Store array size
      movl  12(%ebp), %ecx
      decl  %ecx

# Prepare for outer loop here
      xorl  %esi, %esi

outer_loop:
# This stores the min index
      movl  %esi, -4(%ebp)
      movl  %esi, %edi
      incl  %edi

inner_loop:
      cmpl  $ARRAY_SIZE, %edi
      jge   swap_vars
      xorb  %al, %al
      movl  -4(%ebp), %edx
      movb  (%ebx, %edx, 1), %al
      cmpb  %al, (%ebx, %edi, 1)
      jge   check_next
      movl  %edi, -4(%ebp)

check_next:
      incl  %edi
      jmp   inner_loop

swap_vars:
      movl  -4(%ebp), %edi
      movb  (%ebx, %edi, 1), %dl
      movb  (%ebx, %esi, 1), %al
      movb  %dl, (%ebx, %esi, 1)
      movb  %al, (%ebx,  %edi, 1)

      incl  %esi
      loop  outer_loop

      movl  %ebp, %esp
      popl  %ebp
      ret

exit:
      movl  $1, %eax
      movl  0, %ebx
      int   $0x80

Я прошел через это, и я могу понять 90% того, что происходит, поэтому я доволен этим.То, что я понятия не имею, с чего начать, как взять пользовательский ввод и создать массив с ним?И как мне использовать буфер, чтобы установить ограничение на размер массива?Любая помощь очень ценится!

1 Ответ

1 голос
/ 12 февраля 2011

Эта программа не является интерактивной. «Вход» задается в массиве строк

array:
      .byte  89, 10, 67, 1, 4, 27, 12, 34, 86, 3

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

http://linux.die.net/man/2/read с дескриптором файла stdin (очень низкий уровень, но вы пишете на ассемблере) или http://www.manpagez.com/man/3/scanf/ (функция C). Вы также получите обзор с помощью команды «man scanf» в командной строке.

Вы помещаете аргументы, которые хотите передать функциям, в стек в обратном порядке, вызываете функцию и перенастраиваете стек. То, как аргументы передаются функциям, зависит от архитектуры и операционной системы. Это определяется в двоичном интерфейсе приложения («ABI»). См. http://www.scribd.com/doc/48244725/abi386-4 в разделе «Последовательность вызова функций», если вы используете i386.

Вы можете зарезервировать 1000 байтов в разделе .bss с помощью

.section .bss
buffer:  .space 1000

Или вы можете использовать "malloc".

...