【问题标题】:Inserting values into array in assembly MASM32在程序集 MASM32 中将值插入数组
【发布时间】:2016-11-17 20:43:17
【问题描述】:

我无法弄清楚如何将我当前在寄存器 EAX 中的值放入数组中。

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

我将使用“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

【问题讨论】:

  • datetonum的代码在哪里?
  • @JoseManuelAbarcaRodríguez 我可以包含它 - 但是我不知道有必要看到完成我想要做的事情。它只是将日期中的一个日期转换为唯一的 32 位数字,并将其存储在 EAX 中
  • 好吧,由于缺少MCVE,因此有必要将该代码包含在您的问题中,以防止不被关闭。我强烈推荐它。
  • @zx485 好的,刚刚编辑了我的原始帖子。它现在在那里。
  • lea ECX, ra / mov [ECX + nDates], EAX。两个内存地址的总和不会有用......我在这里没有看到一个特定的问题,或者任何关于什么不起作用或你用调试器发现什么的描述。

标签: arrays assembly x86 masm masm32


【解决方案1】:

如果您的日期存储在一个数组中,并且您想使用另一个数组来存储转换为数字的日期,则至少需要一个循环。您可以使用索引寄存器(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

【讨论】:

  • call datetonum + pop eax: 因为返回值在eax,这看起来不是个好主意。 OP也使用ret 4来弹出参数,所以你不需要pop。
  • 所以,@tay1392,我想我的答案没有用或太复杂,是吗?我在每条指令的右边添加了 cmets 来解释它。我想告诉你将所有日期转换为数字、对它们进行排序并将它们转换回日期的逻辑。
  • @JoseManuelAbarcaRodríguez 这对何塞很有帮助。感谢您抽出宝贵的时间来做这件事。这有点复杂,只是因为我真的对组装不满意。但是您的 cmets 和逻辑是有道理的。最终没有让我的任务发挥作用,但是哦,好吧。再次感谢。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-01-30
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-09-17
相关资源
最近更新 更多