遍历和平均数组MASM中的元素

时间:2015-03-12 18:27:37

标签: c arrays assembly masm

我在x86 masm课程中,我们有一个项目即将出现,我不明白。 TA和教授几乎没用,我一直试图与他们联系一个星期,没有回答,没有办公时间。无论如何,我应该计算15年间每月的平均天数。 (2000-2015)我们也应该考虑闰年。

我事先在C中编写了程序,这是我的代码:

main()
{   
    double sum=0;

    int dpm[12] = {31,28,31,30,31,30,31,31,30,31,30,31};
    int i=0;
    int j=0;
    int months=0;

    while(j<16)
    {
        while(i<12)
        {
            if(j==0 || j==4 || j==8 || j==12)
            {
                dpm[1]=29;
            }
            sum+=dpm[i];
            dpm[1]=28;
            months++;
            i++;
        }
    j++;
    }
    printf("%.2f",sum/months);
}

(我意识到在这里使用for循环会是最好的,但是在asm中循环更容易,所以我使用了while循环)

我不太了解集会,但到目前为止我的目标是:

.DATA

    sum    DWORD 0
    months DWORD 0
    dpm    DWORD 31,28,31,30,31,30,31,31,30,31,30,31
    elm    DWORD 12
    i      WORD  0
    j      WORD  0

.CODE
main

    mov eax, sum            ; move sum to eax
    lea esi, dpm            ; move array to ebx
    mov ecx, elm            ; move no of elements to ecx
    mov ax, j               ; move j to ax
    mov bx, i               ; move i to bx

outterLoop:

    cmp 15, ax              ; compare 15 to i
    jle innerloop           ; jump to inner loop if it is less

innerLoop:

    cmp 11, bx              ; compare 11 to j
    jle checkLeap           ; jump to checkleap if it is less
    inc ax                  ; incremement j

checkLeap:

    cmp 0, bx               ; if j is 0
    je leap                 ; go to leap year function
    cmp 4, bx
    je leap
    cmp 8, bx
    je leap
    cmp 12, bx
    je leap
    jne updates             ; if not, go to updates fn

leap:

    add esi, 4              ; go to second element in array "february"
    mov 29, esi             ; make feb 29 instead of 28

updates:

    add eax, [esi]          ; add element to sum
    add esi, 4              ; increment array

    ; inc months

    mov                     ; here I would make second element of array 28

    inc bx                  ; increment i

我不知道我是否走在正确的轨道上,并希望获得指导,建议。谢谢

2 个答案:

答案 0 :(得分:0)

当与立即值比较时,您需要将数字放在最后。 (纠正7次)

cmp ax, 15           ; compare 15 to i

要更改列表中2月的长度,请使用

mov dword [esi], 29  ; make feb 29 instead of 28

重置它同样的事情

mov dword [esi], 28  ; here I would make second element of array 28

由于您已将 j 索引放在AX寄存器中,因此需要将总和放在与EAX不同的寄存器中。请记住,AX只是EAX的低16位。

下一个代码需要额外的跳转。现在它始终执行 innerLoop

 cmp ax,15       ; compare 15 to i
 jle innerloop   ; jump to inner loop if it is less

innerLoop:

答案 1 :(得分:0)

此代码正常工作,并在edx寄存器中提供正确的输出。

  如果您希望我为此代码添加评论,请在下方发表评论。

我通过必要的更改实现了您的逻辑,问题是您正在实施错误

Include irvine32.inc
.data
; (31==1Fh)(30==1Eh)(28==1Ch)(29==1Dh)
dpm dword   1Fh,1Ch,1Fh,1Eh,1Fh,1Eh,1Fh,1Fh,1Eh,1Fh,1Eh,1Fh
countj  dword   ?
temp    dword   ?
temp1   dword   ?
.code
Main Proc
;   [instr] [destor opp1]   [addtio instr]  [source orOpp2] ;comment
mov ecx,                15      ;intializing to max value of j
mov esi,        offset      dpm     ;storing offset of dpm to esi
mov edx,        0               ;intializing sum to 0
mov ebx,        0               ;intializing counter to 0
mov eax,        0               ;intializing counter to 0
loopj:                              ;loop of j
mov countj,             ecx     ;storing count of j
mov ecx,                12      ;intializing to max value of i
loopi:                              ;loop of i  
inc ebx                 
mov eax,                countj
;start of if statement:
cmp eax,                1       ;jump if j is 1
je  IfJConTrueStart                 
cmp eax,                5       ;jump if j is 5
je  IfJConTrueStart                 
cmp eax,                9       ;jump if j is 9
je  IfJConTrueStart                 
cmp eax,                13      ;jump if j is 13
je  IfJConTrueStart                 
                        ;29
JConMid:
call    dumpregs
mov temp1,              edx     
mov eax,                ecx
mov temp,       type        dpm     
mul temp
add esi,                eax     
sub esi,                temp        
call    dumpregs        
mov edx,                temp1
add edx,                [esi]
call    dumpregs        
sub esi,                eax 
add esi,                temp
call    dumpregs                    
JConEnd:
loop    loopi                       
mov ecx,                countj      
loop    loopj           
jmp skipIfJConTrue                      
IfJConTrueStart:        
cmp ecx,                2
je  IfJConTrueMid
jmp JConMid
IfJConTrueMid:
add edx,                1Dh
jmp JConEnd
skipIfJConTrue:             
call    dumpregs                
Exit
Main endp
End main