Hi guys! im having a problem with an exercise and i can't find the solution. the program have to sub the contents of the second array from the first and mov the result to the third. This is what i did so far.

TITLE ARITHMETIC2
    DOSSEG
    .MODEL SMALL

    .STACK 100h

    .DATA
arrayE DB 112, 112, -32, -32, -128
arrayF DB 80, 120, 112, -80, 128
arrayX DB 2 DUP (10)

    .CODE
start:    MOV AX,@DATA
           MOV DS,AX
    
    MOV SI, OFFSET arrayE
    MOV DI, OFFSET arrayF
    MOV SP, OFFSET arrayX
    MOV CX, 5    
    
loopi:     
    MOV AX, [SI]
    MOV BX, [DI]
    MOV DX, [SP]
    SUB AX , BX
    
    MOV DX, AX
    INC SI
    INC DI
    INC SP ;this is wrong, what should i write here?
    LOOP loopi
terminate:    MOV AX, 4C00H
    INT 21H
    END start

Dani AI

Generated

The goal is simple: compute arrayX[i] = arrayE[i] - arrayF[i] for 5 byte elements. The original mistakes were: using SP as an array pointer (SP is the stack pointer and should not be repurposed), loading words when the data are bytes (using AX reads two bytes), and not storing the result (as pointed out). ’s suggestion to use string instructions is valid and often faster, but ES must be set for destination and direction (DF) cleared before using them.

A compact, correct byte-oriented loop (assuming DS is already set to the data segment):

mov si, OFFSET arrayE    ; source 1
mov bx, OFFSET arrayF    ; source 2
mov di, OFFSET arrayX    ; destination
mov cx, 5

sub_loop:
    mov al, [si]         ; load byte from arrayE
    sub al, [bx]         ; subtract byte from arrayF
    mov [di], al         ; store result in arrayX
    inc si
    inc bx
    inc di
    loop sub_loop

Troubleshooting notes:

  • If elements are declared with DB, use AL (byte ops). If using DW (words), use AX and increment SI/BX/DI by 2.
  • Ensure DS is initialized to the data segment before the loop. If using STOSB/LODSB, set ES = DS and clear DF (CLD).
  • Signed vs unsigned: DB stores two's‑complement bytes. OF (overflow) flags signed overflow; CF (carry) flags unsigned borrow. Use JO to detect signed overflow or JC to detect unsigned borrow if those conditions matter.
  • To avoid wraparound for large results, sign-extend operands into 16 bits (or store results as words) before subtracting.

This addresses ’ original intent while tying in ’s and ’s points without repurposing SP or mixing operand sizes.

Recommended Answers

All 2 Replies

You simply forgot to store the result to the final array.

loopi:
MOV AX, [SI]
MOV BX, [DI]
MOV DX, [SP]
SUB AX , BX

MOV DX, AX
MOV [SP], DX   <<<  add this line
INC SI
INC DI
INC SP ;this is wrong, what should i write here?
LOOP loopi

Nathan.

SP is a special purpose register and it should never be used for anything other than what it was intended and you realize that anyway by your comment this is wrong. You've got the right idea using index registgers, but you're failing to use instructions that give these registers thier potential, like LODS & STOS.

loopi:
        lodsb
        sub      al, [di]
        stosb
        loop     loopi

In the first part of you app move the contents of arrayE to arrayX and then setup

mov     si, arrayE
        mov     di, arrayX
        mov     cx, 5
        rep     movsb

Then you can execute the snippet before this one. Realize my example is over simplistic and I use NASM, but I sure you'll get the idea.

In assembly programming try to avoid moving data from memory to register, doing a calculation and then moving back again. There is unecessary overhead in both code and time.

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.