Assembly 我的项目赢了';对大于130的数组进行t排序

Assembly 我的项目赢了';对大于130的数组进行t排序,assembly,x86,masm,irvine32,Assembly,X86,Masm,Irvine32,所以我的程序应该接受用户输入(10到200之间的整数),然后打印出一个随机数数组,然后打印出该数组的排序版本。然而,这只在我输入130或更少时有效 我不知道我还能做什么。它起作用了,但只起了一半作用。有没有办法优化这段代码?我已经放置了一些行来帮助显示我遇到的问题 ****我运行了调试器,并在程序抛出异常错误的地方留下了注释***** TITLE Program5 (Program5.asm) INCLUDE Irvine32.inc ; (insert constant defini

所以我的程序应该接受用户输入(10到200之间的整数),然后打印出一个随机数数组,然后打印出该数组的排序版本。然而,这只在我输入130或更少时有效

我不知道我还能做什么。它起作用了,但只起了一半作用。有没有办法优化这段代码?我已经放置了一些行来帮助显示我遇到的问题

****我运行了调试器,并在程序抛出异常错误的地方留下了注释*****

TITLE Program5    (Program5.asm)

INCLUDE Irvine32.inc

; (insert constant definitions here)
    MIN_INPUT = 10
    MAX_INPUT = 200
    LO_RANDOM = 100
    HI_RANDOM = 999

.data

; (insert variable definitions here)
intro           BYTE    "Fun with Arrays! by ", 0
instruction     BYTE    "This program generates random numbers in the range [100 .. 999], displays the original list, sorts the list, and calculates the median value. Finally, it displays the list sorted in descending order", 0

request         DWORD   10
ask_user        BYTE    "How many numbers should be generated? [10 ... 200]: ", 0
error           BYTE    "Invalid input", 0

title_1         BYTE    "The unsorted random numbers: ", 0
title_2         BYTE    "The sorted list: ", 0
space           BYTE    "   ", 0

mult            DWORD   0.5

temp            DWORD   0

list            DWORD   MAX_INPUT   DUP(?)

.code
main PROC

; (insert executable instructions here)
    call    randomize
    call    introduction

    push    OFFSET request ;passed by reference
    call    getData

    call    CrLf

    push    request ; passed by value
    push    OFFSET list ; passed by reference
    call    fillArray

    push    OFFSET list
    push    request
    push    OFFSET title_1
    call    displaylist

    call    CrLf

    push    OFFSET list
    push    request
    call    sortList

    call    CrLf
;
    push    OFFSET list
    push    request
    push    OFFSET title_2
    call    displaylist

    ;push   OFFSET list
    ;push   request
    ;call   displayMedian

    exit    ; exit to operating system
main ENDP

; (insert additional procedures here)
introduction PROC

    mov     edx, OFFSET intro
    call    WriteString
    call    CrLf
    mov     edx, OFFSET instruction
    call    WriteString
    call    CrLf
    ret 

introduction ENDP

getData PROC
;include parameter - request (reference)

    push    ebp ;Set up stack frame
    mov     ebp, esp

    ;get an integer from user
    mov     ebx, [ebp+8]    ;get address of request into ebx

    L1:
        mov     edx, OFFSET ask_user
        call    WriteString
        call    ReadDec

        cmp     eax, MIN_INPUT
        jl      errorMessage
        cmp     eax, MAX_INPUT
        jg      errorMessage

        cmp     eax, MIN_INPUT
        jge     endThis
        cmp     eax, MAX_INPUT
        jle     endThis

    errorMessage:
        mov     edx, OFFSET error
        call    WriteString
        call    CrLf
        jmp     L1

    endThis:
        mov     [ebx], eax
        pop     ebp
        ret     4 ; remove four more bytes from the stack (after ret @)
getData ENDP

fillArray PROC
;include parameters - request (value), array (reference)
    ; MAJORITY OF THE FOLLOWING CODE WAS EXTRACTED FROM LECTURE 20 SLIDES
    push    ebp
    mov     ebp, esp ;[ebp+4]
    mov     edi, [ebp+8] ; @list in edi
    mov     ecx, [ebp+12] ; value of request in ecx

    more:
        mov     eax, HI_RANDOM
        sub     eax, LO_RANDOM
        inc     eax
        call    RandomRange
        add     eax, LO_RANDOM

        mov     [edi], eax
        add     edi, 4
        loop    more

    endmore:
        pop     ebp
        ret     8
fillArray ENDP

;----------------------------------------------------------------------------
;----------------------------------------------------------------------------
;----------------------------------------------------------------------------
sortList PROC
;include parameters - array (reference), request (value)
    push    ebp
    mov     ebp, esp ;[ebp+4]
    mov     edi, [ebp+12] ; @list in edi
    mov     ecx, [ebp+8] ; value of request in ecx

    dec     ecx ; request - 1
    mov     ebx, 0 ; "k"

    ;for(k=0; k<request-1; k++) { 
       ;i = k; 
       ;for(j=k+1; j<request; j++) { 
          ;if(array[j] > array[i]) 
             ;i = j; 
       ;} 
       ;exchange(array[k], array[i]); 
    ;} 

    firstLoop:
        mov     eax, ebx ; "i = k"

        mov     edx, ebx ; "j = k"
        inc     edx ; "j = k + 1"
        push    ecx ; pushed the first loop's counter
        mov     ecx, [ebp+8] ; made the second loop's counter = request

        secondLoop:
            mov     esi, [edi + (edx * 4)] ; array[j] ; EXCEPTION WAS THROWN HERE
            cmp     esi, [edi + (eax * 4)] ; compare array[j] and array[i]
            jg      greater
            jle     lesser

            greater:
                mov     eax, edx
                inc     edx
                loop    secondLoop

            lesser:
                inc     edx
                loop    secondLoop

        push    edx
        push    esi
        push    [edi + (ebx * 4)] ; array[k]
        push    [edi + (eax * 4)] ; array[i]
        call    exchangeElements
        pop     [edi + (eax * 4)]
        pop     [edi + (ebx * 4)]
        pop     esi
        pop     edx
        pop     ecx ; set the 
        inc     ebx ; increment k in the first loop
        loop    firstLoop

    pop     ebp
    ret     8

sortList ENDP

exchangeElements PROC
    push    ebp
    mov     ebp, esp
    mov     esi, [ebp+12] ; array[k]
    mov     edx, [ebp+8] ; array[i]
    mov     [ebp+8], esi
    mov     [ebp+12], edx
    pop     ebp
    ret     
exchangeElements ENDP
;----------------------------------------------------------------------------
;----------------------------------------------------------------------------
;----------------------------------------------------------------------------

displayMedian PROC
    push    ebp
    mov     ebp, esp ;[ebp+4]
    mov     edi, [ebp+12] ; @list in edi
    mov     ecx, [ebp+8] ; value of request in ecx

    mov     eax, ecx
    mov     ebx, 2
    cdq
    div     ebx
    cmp     edx, 0
    je      isEven
    cmp     edx, 1
    je      isOdd

            ;def nlogn_median(l):
    ;l = sorted(l)
    ;if len(l) % 2 == 1:
        ;return l[len(l) / 2]
    ;else:
        ;return 0.5 * (l[len(l) / 2 - 1] + l[len(l) / 2])

    isEven:
        mov     esi, [edi + (eax - 1)]
        add     esi, [edi + (eax)]
        mov     eax, esi
        mov     ebx, 2
        cdq
        div     ebx
        call    WriteDec

    isOdd:
        mov     eax, [edi + (eax*4)]
        call    WriteDec

    pop ebp
    ret
displayMedian ENDP

displayList PROC
    push    ebp
    mov     ebp, esp ; [ebp+4]
    mov     ecx, [ebp+12] ; @request
    mov     edi, [ebp+16] ; @list
    mov     esi, 10

    mov     edx, [ebp+8] ; @title
    call    WriteString
    call    CrLf

    show:
        mov     eax, [edi]
        call    WriteDec
        mov     edx, OFFSET space
        call    WriteString
        add     edi, 4

        dec     esi
        cmp     esi, 0
        je      callClear

    loopAgain:
        loop    show

    jmp     endshow

    callClear:
        mov     esi, 10
        call    CrLf
        jmp     loopAgain

    endshow:
        pop     ebp
        ret     12

displayList ENDP

END main
标题程序5(Program5.asm)
包括Irvine32.inc
; (在此处插入常量定义)
最小输入=10
最大输入=200
LO_RANDOM=100
HI_RANDOM=999
.数据
; (在此处插入变量定义)
简介字节“数组的乐趣!由”,0
指令字节“此程序生成[100..999]范围内的随机数”,显示原始列表,对列表进行排序,并计算中值。最后,按降序显示列表”,0
请求DWORD 10
询问用户字节“应生成多少个数字?[10…200]:”,0
错误字节“无效输入”,0
标题_1字节“未排序的随机数:”,0
标题_2字节“排序列表:”,0
空格字节“”,0
多德沃德0.5
临时DWORD 0
列出DWORD最大输入DUP(?)
.代码
主进程
; (在此处插入可执行指令)
呼叫随机化
电话介绍
推送偏移请求;参照传递
调用getData
呼叫CrLf
推送请求;按值传递
推送偏移列表;参照传递
调用填充数组
推送偏移列表
推送请求
推送偏移标题_1
呼叫显示列表
呼叫CrLf
推送偏移列表
推送请求
呼叫分拣员
呼叫CrLf
;
推送偏移列表
推送请求
推送偏移标题2
呼叫显示列表
;推送偏移列表
;推送请求
;呼叫显示中位数
出口退出操作系统
主端
; (在此插入其他程序)
介绍过程
mov edx,偏移量介绍
通话记录
呼叫CrLf
偏移指令
通话记录
呼叫CrLf
ret
导言
获取数据过程
;包含参数-请求(参考)
推动ebp;设置堆栈框架
电动汽车
;从用户处获取整数
mov-ebx,[ebp+8];将请求地址获取到ebx中
L1:
mov edx,偏移量询问用户
通话记录
呼叫ReadDec
cmp eax,最小输入
jl错误消息
cmp eax,最大输入
jg错误消息
cmp eax,最小输入
jge endThis
cmp eax,最大输入
jle endThis
错误消息:
偏移量误差
通话记录
呼叫CrLf
jmp-L1
完此:
mov[ebx],eax
流行ebp
ret4;从堆栈中再删除四个字节(在ret@之后)
getData ENDP
填充数组过程
;包括参数-请求(值)、数组(参考)
; 以下大部分代码摘自第20课的幻灯片
推ebp
mov-ebp,esp;[ebp+4]
移动电子数据交换[ebp+8]@电子数据交换中的列表
mov-ecx,[ebp+12];ecx中请求的值
更多:
mov-eax,HI_-RANDOM
子eax,LO_随机
埃克斯公司
呼叫随机范围
加上eax,lou随机
mov[edi],eax
添加edi,4
循环更多
endmore:
流行ebp
ret 8
fillArray ENDP
;----------------------------------------------------------------------------
;----------------------------------------------------------------------------
;----------------------------------------------------------------------------
排序程序
;包括参数-数组(参考)、请求(值)
推ebp
mov-ebp,esp;[ebp+4]
移动电子数据交换[ebp+12]@电子数据交换中的列表
mov-ecx,[ebp+8];ecx中请求的值
dec-ecx;请求-1
mov-ebx,0;“k”

;对于(k=0;k如果你查看你的寄存器,你会发现
edx
0fA4h
,它比它崩溃时所在的行要大。
ecx
是一个负数。这是循环应该停止后执行的线索

问题是
较大的
分支将通过
较小的
分支。这将再次减小
ecx
,导致其变为负值,循环将继续运行,直到您获得访问冲突

快速修复方法是在
更大的
标签下的
循环
指令之后放置一个无条件的
jmp

更好的解决方法是将循环的尾部组合成更简单的条件:

    cmp     esi, [edi + (eax * 4)] ; compare array[j] and array[i]
    jle     lesser
    mov     eax, edx
lesser:
    inc     edx
    loop    secondLoop

确切地说是130吗?如果你在某处截短到字节,127是最大的有符号字节,128或更高可能“看起来像”一个负数。当你的代码出错时,寄存器中的值是什么?EDI中的基是否正确,EDX中的索引是否在范围内?它是否在第一次迭代时出错,或者由于某种原因在循环结束数组后出错?如果我输入130,则程序打印出130个随机数的数组。然后打印出相同的数组,但从最大值到最小值排序。如果我在131中输入,则在屏幕上打印出未排序的数组后,程序崩溃。我将发布寄存器值的屏幕截图。在您逐步查看发生了什么情况后,调试器会告诉您什么?调试器还应告诉您指令是否访问了错误地址。当它输入s second循环,它会被卡住一段时间,然后停止程序并抛出异常
0x0040a000
是新页面的开始,因此