2016-11-14 91 views
1

我一直在研究一个汇编程序,它对日期列表进行排序,然后打印出排序最早的日期到最新的日期。日期格式为DD-MMM-YYYY,例如, “23-JUL-2010”。在调试汇编程序时遇到问题排序日期

我已经取得了稳定的进展,但现在我的程序马上崩溃了,而且我很难找出原因。我正在使用MASM32编辑器。

这是我的计划......

include \masm32\include\masm32rt.inc 

.data? 
number dd ? 
.data 

dates BYTE "23-JUL-2010", 0, "22-JUL-2010", 0, "23-JUL-2009", 0, "31-JUL-2012", 0, "05-MAR-2010", 0, "12-MAR-1010", 0 
values dd 5 DUP(0, 0, 0, 0, 0) 
nDates DWORD 6 
counter DD 0 
temp dd 0 
years dd 0 
months BYTE "JAN FEB MAR APR MAY JUN JUL AUG SEP OCT NOV DEC",0 

.code 

DateToNumber MACRO items, mons, result 
    LOCAL loop_top 
    PUSHAD 

    lea EDI, [items] 
    MOV AL, [EDI] 
    AAA 
    MOV BL, 10 
    MUL BL 
    MOV DL, AL 
    ADD EDI, 1 
    SUB EAX, EAX 
    MOV AL, [EDI] 
    AAA 
    ADD DL, AL 
    MOV result, EDX 
    SUB EDX, EDX 
    SUB ESI, ESI 
    SUB EDI, EDI 
    mov EAX, 0   ; EAX is the month number 

    loop_top: 
     lea ESI, [items+3] ; ESI will be a ptr into the date string we are trying to convert to a number 
     lea EDI, [mons + EAX * 4] ; EDI will be a ptr into the months array 

     inc EAX 
     mov ECX, 3   ; length of a month string 
     cld 
     repe cmpsb   ; compare mystring and months for 3 characters 

     jne loop_top  ; keep looping until we find the month 

    mov EBX, result 
    mov BH,AL 
    SUB EBX, EBX 
    MOV years, EBX 
    lea EDI, [items] 
    ADD EDI,7 
    MOV AL, [EDI] 
    AAA 
    MOV BX, 1000 
    MUL BX 
    MOV years, EAX 
    SUB BX, BX 
    SUB EAX, EAX 
    ADD EDI, 1 
    MOV AL, [EDI] 
    AAA 
    MOV BX, 100 
    MUL BX 
    SUB BX, BX 
    ADD years, EAX 
    SUB EAX, EAX 
    ADD EDI, 1 
    MOV AL, [EDI] 
    AAA 
    MOV BX, 10 
    MUL BX 
    SUB BX, BX 
    ADD years, EAX 
    SUB EAX, EAX 
    ADD EDI, 1 
    MOV AL, [EDI] 
    AAA 
    SHL EAX, 16 
    ADD result, EAX 
    POPAD 
ENDM 


start: 
    MOV ECX, 1 
    SUB EDX, EDX 
    SUB EAX, EAX 
    DateToNumber dates, months, number 
    MOV EAX, number 
    MOV values, EAX 
    DateToNumber [dates+12], months, number 
    MOV EAX, number 

    MOV [values+4], EAX 
    DateToNumber [dates+24], months, number 
    MOV EAX, number 
    MOV [values+8], EAX 
    DateToNumber [dates+48], months, number 
    MOV EAX, number 
    MOV [values+16], EAX 
    DateToNumber [dates+36], months, number 
    MOV EAX, number 
    MOV [values+12], EAX 
    DateToNumber [dates+60], months, number 
    MOV EAX, number 
    MOV [values+20], EAX 
    print chr$("[ ",) 

    ;lea EDI, [values] 
    ;push EDI 
    ;Call BubbleSort 

    ;Call NumberToDate 
out_top: 

    mov eax, [values+esi*4] 
    mov temp, eax 
    print str$(temp) 
    print chr$(", ") 
    inc esi 
    cmp esi, 5 
    jne out_top 

    ; Formatting the last character 
    mov eax, [values+esi*4] 
    mov temp, eax 
    print str$(temp) 
    print chr$(" ]", 13, 10) 
exit 

;NumberToDate- 
; Parameter is a 32-bit unsigned number. 
; Turns the number back into its corresponding date string. 
; Returns the address of the string. 
; 
NumberToDate : 

    enter 0, 0 

    print "NumberToDate called" 
    leave 
    ret 0 

;BubbleSort- 
; Parameters are the address of an array of 32-bit unsigned numbers and the length of the array. 
; Sorts the array in place from smallest to largest. 
; No return value. 
; 
BubbleSort: 

    enter 0, 0 
    PUSHAD 
    mov ecx, 0 
    mov edx, 0 
    print "BubbleSort called" 

    MOV ESI, [EBP + 8] 

    top: 
     cmp edx, 5 
     je inc_loop 
     inc edx   
     mov eax, [esi+ecx*4] ; moves array index 0 into eax 

     cmp [esi+edx*4], eax ; compares index 1 to index 2 
     jl top    ; jumps to top if index1 is less than or equal to index 2 

     ; swaps the values edx and ecx are pointing to 
     mov ebx, [esi+edx*4] 
     mov [esi+ecx*4], ebx 
     mov [esi+edx*4], eax 
     jmp top 

    inc_loop: 
     mov edx, -1 
     inc ecx 
     cmp ecx, 5 
     jl top 

    POPAD 
    leave 
    ret 4 

END start 

如果你们能帮助我理解我要去哪里错了,还是帮我调试此我将不胜感激。提前致谢!

+0

您是否尝试过使用调试器?这是一个程序,可让您单步执行程序并查看寄存器/内存。或者让它运行,并告诉你它在崩溃点的状态。调试器对编写asm非常有帮助:在没有人的情况下工作就像试图在蒙上眼睛时构建机器人一样。 –

+0

所以用MASM进行组装并用别的东西进行调试。咄。我的C编译器不是一个调试器(更不用说编辑器了)。我使用GDB来调试程序集C和C++。 –

回答

0
out_top: 
    mov eax, [values+esi*4] 
    mov temp, eax 
    print str$(temp) 
    print chr$(", ") 
    inc esi 
    cmp esi, 5 
    jne out_top 

在程序中的这一部分,你在ESI取决于正确的值,但你忘了初始化!

XOR ESI, ESI  <<<< Add this line 
out_top: 
    mov eax, [values+esi*4] 
    mov temp, eax 
    print str$(temp) 
    print chr$(", ") 
    inc esi 
    cmp esi, 5 
    jne out_top 

values dd 5 DUP(0, 0, 0, 0, 0) 

看到这个我怀疑你不懂DUP运营得非常好!
您的代码需要预留6个双字的空间,但是此行保留25个这样的双字。写出下列之一:

values dd 0,0,0,0,0,0 

否则

values dd 6 dup(0) 

有您DateToNumber代码为宏浪费了大量的字节。这本应该写成一个子程序。
请记住,每次你使用使用宏时,整个代码片段都会被替换。在你的程序中这发生了6次。

+1

谢谢你的帮助!我很感激。 – tay1392