Academic Integrity: tutoring, explanations, and feedback — we don’t complete graded work or submit on a student’s behalf.

Write a program to count how many entries in an N-byte array are positive, negat

ID: 2268031 • Letter: W

Question

Write a program to count how many entries in an N-byte array are positive, negative, even, and/or odd. The array should be stored starting at memory location $100. The value of N should be set in your code using the assembly directive ‘EQU’. An entry is considered positive if its MSB is ‘0’ and negative if it’s ‘1’. An entry is considered even if its LSB is ‘0’ and odd if it’s ‘1’. The four count values should be stored at memory locations $00-$03 in the following order: negative count, positive count, even count, odd count. Your code instructions should be stored starting at memory location $B600 (EEPROM).

I am using MiniIDE and Buffalo Monitor to run and test the code.

This is what I have so far:

* data storage declaration

org $00 ; start at memory location $00

neg rmb 1 ; 1 byte reserved for negative count

pos rmb 1 ; 1 byte reserved for positive count

even rmb 1 ; 1 byte reserved for even count

odd rmb 1 ; 1 byte reserved for odd count

N equ 20 ; array count

org $100 ; start at memory location $100

array fcb

* program instruction

ldaa array ; set [A] to array[0]

ldab #1 ; initialize loop index to 1

loop ldx #array ; point X to array[0]

abx ; compute the address of array[i]

cmpa 0,X ; compare temp array max to the next element

bhs chkend

ldaa 0,X

chkend cmpb #N-1 ; compare loop index with loop limit

beq exit ; if loop counter = array count, exit

incb ; increment loop counter

bra loop ; branch up to 'loop'

exit staa neg ; stores the number of all negative numbers

staa pos ; stores the number of all positive numbers

staa even ; stores the number of all even numbers

staa odd ; stores the number of all odd numbers

swi

Thanks!

Explanation / Answer

section .rodata

word_array dw -1,2,-3,4
len equ $-word_array ; length in bytes. assembler constant, so we can mov reg, imm8/imm32 rather than loading it as data.

section .text
proc:
mov esi, word_array ; esi points to the array. In MASM, use OFFSET word_array
mov ecx, len/2 - 1 ; [esi + ecx*2] points to the last element
xor edx, edx ; non_neg_count = 0

countloop:
; cmp [esi + ecx*2], 0 ; This can't macro-fuse (memory and immediate operand). Also can't micro-fuse on SnB, because of a 2-reg addressing mode
movsx eax, word [esi + ecx*2] ; use a 2-reg addressing mode to save loop overhead, since this there's no ALU execution port component to this insn. It doesn't need to micro-fuse to be one uop
test eax, eax ; can macro-fuse with js
js isNegative
inc edx ; counting non-negative numbers
isNegative:
dec ecx ; can macro-fuse with jge, but probably won't unless alignment stops it from being decoded in the same cycle as the earlier test/js
jge countloop ; jge, not jnz, because we want ecx from [0 : len-1], rather than [1 : len]

; after the loop, ecx=-1, edx=non_neg_count
; neg_count = array_count - non_neg_count
mov eax, len/2
sub eax, edx ; eax = neg_count

ret ; return values in eax:edx

positive vs negative

section .rodata

word_array dw -1,2,0,-3,4
len equ $-word_array ; length in bytes. assembler constant, so we can mov reg, imm8/imm32 rather than loading it as data.

section .text
proc_pos_and_neg:
mov esi, word_array ; esi points to the array. In MASM, use OFFSET word_array
xor edx, edx ; pos_count = 0
xor eax, eax ; neg_count = 0
mov ebp, -1 ; constant to test with

lea edi, [esi + len] ; points one past the end of the array
xor ebx, ebx ; clear upper portion, because setcc r32 isn't available, only setcc r8 :(

countloop:
test bp, word [esi] ; test reg, mem can micro-fuse, but test mem, imm can't
setg bl ; 0 or 1, depending on array[i] > 0
lea edx, [edx + ebx] ; add without affecting flags
setl bl
add eax, ebx ; can clobber flags now

add esi, 2 ; extra loop overhead compared to the scan-backwards decrementing an index reg I used last time
cmp esi, edi
jb countloop ; loop while our pointer is below the pointer to one-past-the-end

ret ; neg_count in eax, pos_count in edx

another method
proc:
mov si, data ; si points to the data
mov cx, [len] ; cx gets the length of the data
shr cx,1 ; the length was in bytes, we want words
mov bx, 0
mov dx, cx

checkNext:
mov ax, [si]
text ax, ax ; alternatively: test ax, 8000h
js isNegative
inc bx ; counting positive numbers

isNegative:
add si, 2 ; moving to next word
loop checkNext ; decrease cx, jump if not 0

sub dx, bx ; bx has the positive numbers, dx - the negative ones
ret ; done

data dw -1,2,-3,4
len dw $-data

TO FIND EVEN AND ODD NUMBERS

MVI C,00

MVI D,00

MVI E,00

LXI H,4200

MOV B,M

INX H

LXI H,4200

MOV B,M

LABEL4:INX H

MOV A,M

CPI 00

JNZ LABEL1

INR C

JNZ LABEL2

LABEL1:RRC

JNZ LABEL3

INR D

JMP LABEL2

LABEL3:INR E

LABEL2:DCR B

JNZ LABEL4

INX H

MOV A,C

MOV M,A

INX H

MOV A,D

MOV M,A

INX H

MOV A,E

MOV M,A

HLT

SAMPLE OUTPUT


ADDRESS

DATA

INPUT/OUTPUT

4200

09

Input

4201

00

Input

4202

06

Input

4203

02

Input

4204

11

Input

4205

0A

Input

4206

0D

Input

4207

00

Input

4208

0F

Input

4209

10

Input

420A

02

Output

420B

04

Output

420C

03

Output

Hire Me For All Your Tutoring Needs
Integrity-first tutoring: clear explanations, guidance, and feedback.
Drop an Email at
drjack9650@gmail.com
Chat Now And Get Quote