2016-11-17 4 views
0

У меня возникли проблемы с выяснением того, как поместить значение, которое я сейчас имею в регистре EAX, в массив.Вставка значений в массив в сборке MASM32

Основная функция этой программы - взять массив дат, преобразовать их в уникальные числа, BubbleSort их и преобразовать обратно.

Я положил значения, которые я нахожу с помощью «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 
+0

Где код 'datetonum'? –

+0

@ JoseManuelAbarcaRodríguez Я могу включить его - однако я не знаю, что нужно видеть, чтобы выполнить то, что я пытаюсь сделать. Он просто преобразует одну из дат из дат в уникальный 32-разрядный номер и сохраняет его в EAX – tay1392

+1

Ну, необходимо включить этот код в свой вопрос для _неоткрытия_ из-за отсутствия [MCVE] (http: // stackoverflow .com/помощь/mcve). Я бы очень предложил. – zx485

ответ

0

Если ваши даты хранятся в массиве, и вы хотите использовать другой массив для хранения даты преобразована в число, вам потребуется по меньшей мере, одну петли. Вы можете использовать индексные регистры (ESI, EDI) для указания на оба массива, затем использовать один регистр для чтения значения из одного массива, а другой регистр - для перемещения значения в другой массив.

Давайте представим, у вас уже есть следующие 3 процедуры:

  • num2date: преобразует Num в EAX обратно в дату (противоположность datetonum). Эта дата хранится в переменной date, которая объявляется следующим образом: date BYTE "DD-MMM-AAAA".
  • bubble_sort: сортирует числа в массиве ra.
  • transfer_date: принимает 11 байт переменной date и переместить их в положение, указываемой 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 
+0

'call datetonum' +' pop eax': поскольку возвращаемое значение находится в 'eax', это не похоже на хорошую идею. Кроме того, OP использует 'ret 4', чтобы выставить аргумент, поэтому вам не нужно' pop'. – Ped7g

+0

Итак, @ tay1392, я думаю, мой ответ не был полезен или слишком сложным, не так ли? Я добавил комментарии о праве каждой инструкции, чтобы объяснить это. Я хотел рассказать вам логику конвертировать все даты в числа, сортировать их и преобразовывать их в даты. –

+1

@ JoseManuelAbarcaRodríguez Было полезно Хосе. Я ценю, что вы тратите время на это. Это было немного сложно, потому что мне вообще не нравится сборка. Но ваши комментарии и логика имеют смысл. Не закончил тем, что мое задание работает, но хорошо. Еще раз спасибо. – tay1392