在程序集MASM32

时间:2016-11-17 20:43:18

标签: arrays assembly x86 masm masm32

我无法弄清楚如何将我目前在注册EAX中的值放入数组中。

这个程序的基本功能是获取日期数组,将它们转换为唯一数字,然后将它们冒出来并将它们转换回来。

我把我找到的值与#34; datetonum"进入EAX,我想将我找到的值存储到名为ra的数组中。

我似乎无法弄清楚如何做某事 好像它应该相当简单?

提前致谢!

include \masm32\include\masm32rt.inc
.data
  dates  BYTE "23-JUL-2010", 0, "23-JAN-2010", 0, "23-JUL-2009", 0, "31-JUL-2012", 0, "05-MAR-2010", 0
  months BYTE "JAN",0,"FEB",0,"MAR",0,"APR",0,"MAY",0,"JUN",0,"JUL",0,"AUG",0,"SEP",0,"OCT",0,"NOV",0,"DEC",0
  nDates DWORD 4
  ra     DWORD 1,0,0,0,0

.code
start:
    lea  EAX, dates     ; create pointer to beginning of dates array
    push EAX
    call datetonum

    ;-------------------
    ;put value currently in EAX into array to be sorted
    ;-------------------
    print "Array to be sorted contents: "
    print chr$(13,10)


    lea ECX, ra
    mov [ECX + nDates], EAX
    print ra
    print chr$(13,10)

这是datetonum功能

;param1 (date string) = address of 12 byte date
datetonum:
    enter 4, 0                    ; [EBP - 4] holds 4 byte temp variable
    mov  EBX, [EBP + 8]           ; pointer to entire date string
    lea  ESI, [EBX]               ; pointing to day part of date
    lea  EDI, [EBP - 4]           ; pointing to address of local variable to store day string
    mov  ECX, 2
    cld
    rep  movsb
    mov  EDX, 0
    mov  [EDI], EDX               ; add null terminator

    lea  EDX, [EBP - 4]
    mov  EAX, sval(EDX)           ; convert day string to int
    push EAX                      ; push EAX to stack


    ; extract month from date
    lea  ESI, [EBX + 3]           ; pointing to month part of date
    lea  EDI, [EBP - 4]           ; pointing to address of local variable to store month string
    mov  ECX, 3
    cld
    rep  movsb
    mov  EDX, 0
    mov  [EDI], EDX               ; add null terminator



    ; debug print of month string
    pushad
    lea  EDX, [EBP - 4]
    print EDX
    print chr$(9)                 ; print a tab character
    print chr$(13,10)
    popad

    ; find month number
    sub ESI, ESI
    lea EDX, [EBP - 4]
    mov EAX, [EDX]
    mov ECX, 12
search_top:
    lea EDX, [months + ESI * 4]
    mov EBX, [EDX]
    inc ESI
    cmp EAX, EBX
    loopne search_top

    mov EDX, ESI                    ; result is in ESI

    pop EAX                         ; pop EAX off the stack
    mov AH, DL                      ; copy the month int into AH
    push EAX                        ; push EAX to stack

    ; convert year chars to 2 byte int
    mov EBX, [EBP + 8]
    lea ESI, [EBX + 7]              ; pointing to year part of date
    lea EDI, [EBP - 4]              ; pointing to address of local variable to store year string
    mov ECX, 4
    cld
    rep movsb
    mov EDX, 0
    mov [EDI], EDX                  ; add null terminator

    lea EDX, [EBP - 4]
    mov EDX, sval(EDX)              ; convert year string to int

    pop EAX                         ; pop EAX off the stack
    mov EBX, EAX                    ; copy EAX (contains month in AH and day in AL) to EBX
    mov EAX, EDX                    ; copy year to EAX
    shl EAX, 16                     ; shift the year over to high 16 bits in EAX
    mov AX, BX                      ; copy the month and day into low 16 bits in EAX

    ;print EAX ; this crashes the proc
    print str$(EAX)
    print chr$(13,10)

    leave
    ret 4
    exit

1 个答案:

答案 0 :(得分:0)

如果您的日期存储在数组中,并且您希望使用另一个数组来存储转换为数字的日期,则至少需要一个循环。您可以使用索引寄存器(ESI,EDI)指向两个数组,然后使用一个寄存器从一个数组中读取值,另一个寄存器将值移动到另一个数组中。

让我们假设你已经有了接下来的3个程序:

  • num2date:将EAX中的num转换回日期(与datetonum相反)。此日期存储在变量date中,声明如下:date BYTE "DD-MMM-AAAA"
  • bubble_sort:对数组ra中的数字进行排序。
  • transfer_date:获取变量date的11个字节,并将它们移动到ESI指向的位置(ESI指向数组dates内的某个位置)

这可能是您的代码的逻辑:

start:
;▼ NEXT LOOP CONVERTS ALL DATES TO NUMBERS ▼
    lea ESI, dates      ;POINTER TO ARRAY "DATES".
    lea EDI, ra         ;POINTER TO ARRAY "RA".
    mov ECX, 5          ;LENGTH OF ARRAY "DATES".
dates2numbers:
    push ECX ESI EDI    ;PRESERVE REGISTERS.
    mov  EAX, [ESI]     ;CURRENT DATE.
    push EAX
    call datetonum      ;CONVERT CURRENT DATE TO A NUMBER.
    pop  EAX            ;GET THE NUMBER.
    pop  EDI ESI ECX    ;RESTORE REGISTERS.
    mov  [EDI], EAX     ;STORE NUMBER IN "RA".
    add  ESI, 12        ;NEXT ITEM IN ARRAY "DATES" (12 BYTES EACH).
    add  EDI, 4         ;NEXT ITEM IN ARRAY "RA" (4 BYTES EACH).
    loop dates2numbers

    call bubble_sort    ;◄■■■ SORT ARRAY "RA".

;▼ NEXT LOOP CONVERTS ALL NUMBERS TO DATES ▼
    lea ESI, dates      ;POINTER TO ARRAY "DATES".
    lea EDI, ra         ;POINTER TO ARRAY "RA".
    mov ECX, 5          ;LENGTH OF ARRAY "RA".
numbers2dates:
    push ECX ESI EDI    ;PRESERVE REGISTERS.
    mov  EAX, [EDI]     ;CURRENT NUMBER.
    call num2date       ;CONVERTS EAX TO A DATE IN VARIABLE "DATE".
                        ;VARIABLE "DATE" LOOKS LIKE THIS : DATE BYTE "DD-MMM-AAAA"
                        ;"NUM2DATE" SHOULD PRESERVE ESI AND RESTORE IT
                        ;BECAUSE "TRANSFER_DATE" WILL NEED IT.
    call transfer_date  ;TRANSFER CONTENT OF VARIABLE "DATE" INTO THE
                        ;ARRAY "DATES" AT THE POSITION ESI IS POINTING TO.
    pop  EDI ESI ECX    ;RESTORE REGISTERS.
    add  ESI, 12        ;NEXT ITEM IN ARRAY "DATES" (12 BYTES EACH).
    add  EDI, 4         ;NEXT ITEM IN ARRAY "RA" (4 BYTES EACH).
    loop numbers2dates