When you run the .EXE that TASM creates for you, execution begins at the start label in the code segment and the CS segment register points at it. For your program to function correctly, similarly the DS segment register should point to the data segment of your program. Sadly this is not so by default since DS is pointing at the Program Segment Prefix PSP. You have to setup DS yourself with the following code:
mov ax, @data
mov ds, ax
If you would have chosen for MODEL tiny
(instead of MODEL small
) the problem would not have shown itself since then all 4 segment registers would have been equal to each other.
xor cx,cx
mov cx,8
Zeroing the register before loading the register is an unnecessary operation.
jnc nc
inc al
nc:
Although this construct is correct, incrementing AL if the carry is set can be much simpler via adc al, 0
. If the carry flag is clear nothing is added, and if the carry flag is set then 1 is added.
and al,00000001h
cmp al,0h
Checking whether a value is even/odd is done by looking at the least significant bit which you are doing fine. Point is, you don't need that cmp
afterwards since the and
instruction already defines the zero flag that you want to use for branching.
Better still, if you used test
instead of and
, you would receive the same zero flag and not modify the register at all. Writing test cl, 1
would save you from using the additional register.
jz even_
jnz odd
odd:
This jnz
conditional jump serves no purpose. If the condition is met the execution jumps to the odd label, and if the condition is not met the execution falls through into the odd label.
shr [t_copy],1
You can improve your solution by processing the data from a register instead of from the memory. You would not need the copy either.
CODESEG
start:
mov ax, @data
mov ds, ax
xor cx, cx ; CL is popcount, CH is a convenient 0
mov al, [TAV]
L1:
shr al, 1 ; The bit that comes out of AL
adc cl, ch ; is added to CL
test al, al ; If AL got empty, further adding would be useless
jnz L1
test cl, 1 ; Non-destructive checking of the least significant bit
jnz ON
shr [TAV], cl ; Shift right if popcount is EVEN
jmp exit
ON:
shl [TAV], cl ; Shift left if popcount is ODD
exit: