如何计算MASM中数组中的负数?

时间:2013-04-25 06:55:31

标签: assembly masm

我已经在MASM中编写了一些程序,例如能够根据你提供的数字生成一个字母和空格的三角形,还有一个能够添加和减去并显示它的程序。你给它的数字所以我希望这可以让你了解我知道多少MASM。 我的问题是这个。我得到了一个包含正数或负数的数组。我的工作是通过数组并找出哪个是哪个并返回数组中的负数。我理解我所说的代码是什么意思以及所有单个元素的意思和作用,但我想知道你们是否都可以帮助我弄清楚如何区分负数和正数以便我可以实现它。

;; Do not modify this block of code 
;; (until where comment says you can start your code)
;;
    call Clrscr
    call Randomize       ; Initialize random number generator

;;;;; Generate NUM_NUMS random numbers and store them into the nums array

    mov ecx,NUM_NUMS     ; Number of times to loop
    mov esi,0            ; Relative offset for nums array

NUM_LOOP:
    call Random32        ; Generate a random number
    mov [nums+esi], eax  ; Move random number into array

    add esi,TYPE nums    ; move esi to relative offset of next array element
    LOOP NUM_LOOP        ; end of loop

;;
;; End of do not modify block
;;;;;;;;;;;;;;;;;;;;
;;

1 个答案:

答案 0 :(得分:3)

有很多方法可以做到这一点。例如(顺便说一下,这些都没有被测试,并且没有显示循环逻辑以保持简短)

 1:
  cmp [nums+esi], 0 ; compare with 0
  jnl _skip
  inc edx           ; increment count if < 0
_skip:
 2:
  mov eax, [nums+esi]
  test eax, eax     ; update sign flag with sign bit
  jns _skip
  inc edx           ; increment count if sign was set (ie, < 0)
_skip:
 3:
  mov eax, [nums+esi]
  add eax, eax      ; create unsigned overflow if < 0
  jnc _skip
  inc edx           ; increment count if overflowed (ie, < 0)
_skip:
 4:
  mov eax, [nums+esi]
  shl eax, 1        ; same as 3, but an other way to create overflow
  jnc _skip
  inc edx
_skip:
 5:
  mov eax, [nums+esi]
  add eax, eax
  adc edx, 0        ; add the overflow directly to the count
 6:
  mov eax, [nums+esi]
  shl eax, 1
  adc edx, 0        ; same as 5
_skip:
 7:
  mov eax, [nums+esi]
  sar eax, 31       ; create 0 if non-negative, -1 if negative
  sub edx, eax      ; subtract -1 from count if negative
 8:
  mov eax, [nums+esi]
  shr eax, 31       ; create 0 if non-negative, 1 if negative
  add edx, eax      ; add 1 to count if negative
 9:
  movdqa xmm0, [nums + esi]
  psrad xmm0, 31
  psubd xmm1, xmm0   ; same idea as 7, but with 4 in parallel
 10:
  movdqa xmm0, [nums + esi]
  psrld xmm0, 31
  paddd xmm1, xmm0   ; same idea as 8, but with 4 in parallel
 11:
  cmp [nums+esi], 0
  lea eax, [edx + 1] ; create count+1
  cmovl edx, eax     ; update count with incremented count if < 0
 12:
  xor eax, eax
  cmp [nums+esi], eax
  setl al            ; 0 if non-negative, 1 if negative
  add edx, eax
 13:
  cmp [nums+esi], 0
  setl al
  movzx eax, al    ; same idea as 12, but no recombination penalty
  add edx, eax

无尽的变化。随便挑选。