2011-02-11 3 views
1

사용자가 최대 배열 크기로 입력 한 프로그램을 만들어야 만 사용자가 그 크기의 배열을 만들 수 있습니다. 그 값을 최대 1000 개의 배열 항목 (모든 int)으로 버퍼링해야합니다. 그러면 배열과 출력에 선택 정렬을 실행해야합니다.숙제 도움 - GNU 어셈블러 선택 정렬 질문

IBM 웹 사이트에서 다음 선택 정렬을 발견했습니다.

.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

이 프로그램은 대화 형이 아닙니다. "입력"은 라인 배열에 주어진다.

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

그리고 컴파일 타임 동안에 만 변경 될 수있다. 사용자 입력이 필요한 경우 적절한 커널 함수 나 표준 라이브러리 함수를 호출해야합니다.

http://linux.die.net/man/2/read (매우 낮은 수준이지만 어셈블러 작성 중) 또는 http://www.manpagez.com/man/3/scanf/ (C 함수). 또한 명령 줄에서 "man scanf"에 대한 개요를 볼 수 있습니다.

함수에 전달할 인수를 스택에 역순으로 넣고 함수를 호출 한 다음 스택을 다시 조정합니다. 인수가 함수에 주어지는 방법은 아키텍처와 운영 체제에 따라 다릅니다. 이는 응용 프로그램 2 진 인터페이스 ("ABI")에 정의됩니다. i386을 사용 중이라고 가정하고 "function calling sequence"에서 http://www.scribd.com/doc/48244725/abi386-4을 참조하십시오.

당신은

.section .bss 
buffer: .space 1000 

으로 .bss라고 섹션에서 1000 바이트를 예약 할 수 있습니다 또는 당신은 "malloc에"를 사용할 수 있습니다.

+0

배열의 경우 빈 변수로 초기화해야합니까? array : .int 0 또한 scanf 호출 전에 언젠가 세그먼트 오류가 발생합니다. $ uservalue 및 $ format을 scanf로 순서대로 밀고 있습니다. 여기서 uservalue는 사용자가 원하는 배열 길이를 유지하려는 int 변수이고 형식은 "% d"가있는 asciz 문자열입니다. gdb는 $ uservalue가 푸시 된 직후 세그먼트 오류가 있음을 보여줍니다. 나는 정확한 코드를 1 분 안에 게시 할 것이다. –

+0

'code'.section .DATA MAXVALUE : \t .INT 1,000 형식 : \t .asciz "가 % d" 메시지 : \t .asciz "배열을 정렬 할 수있는 최대 크기를 입력 해주세요. \ n " uservalue : \t .INT \t 값 : \t .INT .section .bss라고 ,.comm array_buffer, 4000 \t 섹션. 텍스트 .GLOBL 주요 \t 주 : \t \t pushl $ 메시지 \t 호출의 printf \t의 movl $ 4 % esp는 \t pushl $의 uservalue \t pushl $ 형식 \t 전화는 scanf \t의 movl $ 8 % esp는 _exit : movl $ 1, % eax movl 0, % ebx int $ 0x80 –

+0

"movel $ 4, % esp"은 틀 렸습니다. stackpointer를 "4"로 덮어 쓰는 것은 의미가 없습니다. 그 후 스택을 사용하는 첫 번째 명령 인 푸시가 충돌합니다. – hirschhornsalz