阵列中的位置和最高值

时间:2015-12-02 00:25:02

标签: assembly masm 32-bit irvine32

所以我正在尝试学习汇编,我的练习表有一个例子,我必须创建一个程序,一次输入10个数字到一个数组。我必须打印最高值并在输入时输出。我在比较中几乎没有任何exp,但我想以某种方式存储高值并将其与位置进行比较?

代码:

include irvine32.inc
.data 
  num  dw 10 dup(0)
  count db 1
  prompt db "Enter a number: ",0
  yesMsg db "hi val is in location ",0
  hiMsg  db "The high value is ",0

.code
main proc
  mov ebx,offset num
  mov ecx,10

LOOP1:
  mov edx,offset prompt
  call writestring
  call readint
  mov [ebx],ax
  add ebx,2
  loop LOOP1

  mov ecx,10
  mov ebx,offset num
  sub eax,eax
  call crlf

LOOP2:
  mov ax,[ebx]
  call writeint
  call crlf
  add ebx,2
  loop LOOP2

  mov ebx,offset num
  mov ecx,lengthof num

FindGreatest:
  call crlf
  mov ebx,offset num
  mov ecx,lengthof num
  mov ax,[ebx]
  movsx eax,ax

FindLoop:
  cmp ax,[ebx]
  jge FindCont
  mov ax,[ebx]

FindCont:
  add ebx,2
  loop FindLoop
  mov edx,offset HiMsg
  call writestring
  call writedec
  call crlf

TestLoop:
  mov eax,ebx
  cmp [ebx],ax
  je IsHighNum

IsHighNum:
  mov edx,offset yesMsg
  call writestring
  movsx eax,count
  call writedec
  call crlf

 ENDITALL:
exit

main endp
end main

我输入1,2,3,4,5,6,7,8,9,10

out:高值是10       高位于1位置

2 个答案:

答案 0 :(得分:1)

你的 FindGreatest 循环应该完成所有工作,而不是让第二个循环(未完成的 TestLoop )找到位置。这是我的建议:

强制此代码至少在我将jge更改为jg后,将当前位置(保存在EDX中)存储到 count 变量中。
通过使用当前位置,可以不再使用ECX寄存器进行循环控制。

FindGreatest:
 call  crlf
 mov   ebx, offset num
 xor   edx, edx
 mov   ax, [ebx]
FindLoop:
 inc   edx          ;Positions 1-10
 cmp   ax, [ebx]
 jg    FindCont
 mov   ax, [ebx]
 mov   count, edx   ;Remember position of greatest
FindCont:
 add   ebx, 2
 cmp   edx, lengthof num
 jb    FindLoop

现在您已准备好在AX中输出结果,并在计数中输出位置。
请记住使用movsx eax, ax对AX进行签名扩展。你不可能在循环之前完成这个,因为如果第一个数字为负数且数组的其余部分至少包含一个正数,那么输出就会出错!

答案 1 :(得分:0)

首先,有一些可读性/性能改进:

替换

mov ax,[ebx]
movsx eax,ax

movsx  eax, word [ebx]

在此代码中:

FindLoop:
  cmp ax,[ebx]
  jge FindCont
  mov ax,[ebx]
FindCont:
  add ebx,2
  loop FindLoop     ; leave an empty line after the loop, not in the middle of the loop and then no space after.

  mov edx,offset HiMsg

在您的循环中,当您发现自己找到了新的最大值时,您已经开始做更多事情。例如将ebx保存到另一个注册表中,例如edx。使用mov旁边的其他mov ax,[ebx]指令执行此操作,因此jge也会跳过它。

在循环结束时,你可以减去指针并右移(除以2)来找到最大元素所在的索引。

或者不是存储指针,而是存储当前值ecx。您正在使用循环计数器指针增量。 loop指令为slow, and not recommended。如果您比较ebx以查看它是否已超过数组末尾,那么您的代码会更好,作为循环条件。