Semicolon
Semicolon

Reputation: 1

how to compare array element in assesmbly?

I'm new to assembly language and I'm trying to do a binary search tree with the following code, however the logic at the bold parts don't seem to be correct...any fix?

        AREA bsttest, CODE, READONLY
        ENTRY
        
Reset_Handler

    ADR r0,Arr ;r0 pointer to arr (array)
    ADR r1,smallest ;r1 pointer to smallest (array)
    ADR r2,greatest ;r2 pointer to greatest (array)
    
    MOV r3,#5 ;5 is the size of array
loop    
    LDRB r5,[r0],#1; load the first element into r5 and set this as root
    **LDRB r6,[r0,#1]** ; load the second element into r6 using pre-increment 
    
    
    CMP r6,r5 ; compare r6 and r5
    BGE storeatright ; if r6 is greater than r5 jump to the label
    
    ;if r6<r5
    **CMP r1,#0**; check if there's a value on the left hand side, if LHS=NULL,
    BGT jump; if it's not NULL, jump
    STRB r6,[r1],#1 ;save and store value at the LHS
jump
    STRB r5,[r1],#1 ;save and store value at the LHS
    
    ;if r6>r5
storeatright 
    
    **CMP r2,#0**; check if there's a value on the right hand side, if RHS=NULL,
    BGT jumps; if it's not NULL, jump
    STRB r6,[r2],#1 ;save and store value at the RHS
jumps
    STRB r5,[r2],#1 ;save and store value at the RHS
    SUBS r3,r3,#1 ; i-- for array
    BNE loop ; loop until array size=0

        
Arr DCB 2,1,4,3,5;array
smallest DCB 0,0,0,0,0 
greatest DCB 0,0,0,0,0

stop    B stop
        END```

Upvotes: 0

Views: 98

Answers (1)

Erik Eidt
Erik Eidt

Reputation: 26666

The first load, ldrb r5,[r0],#1, loads the first byte (from the initial r0), and then increments the pointer, so r0 now points to the 2nd byte of the array (i.e. at index 1).

The second load, ldrb r6,[r0,#1], loads the third byte, because (1) the pointer has been already incremented, and (2) a displacement addressing mode is used with offset=1, so from pointer referring to index 1, adding 1 makes it refer to index 2, which is the third element.


As far as the compare for null, these are good to check but either your logic is bad or the terminology is incorrect..

CMP r1,#0**; check if there's a value on the left hand side, if LHS=NULL,
BGT jump; if it's not NULL, jump
STRB r6,[r1],#1 ;save and store value at the LHS

We wouldn't use BGT to check for NULL, we would instead use BNE there.  So, either the code is checking for >0 integer and the comments are wrong, or the code is incorrectly checking for a NULL pointer.

If the comments are correct that the intent is about checking for NULL, however, the code then goes on to write to memory using that NULL pointer, which would be bad.


I don't see trees involved here — just a few arrays.  Because of that, I would say that the NULL checking is erroneous, and should be removed — just store into the array.  Since you're advancing the pointer after store, its ready for the next store without further checking.


I suggest that you start with a C version of this.  Do all your pointer optimizations in the C version, making sure it actually works.  Then translate your pointer-optimized, working C version to assembly being fairly literal.

Don't start with an array version in C and then try to optimize pointers as you're translating to assembly, unless you want frustration.

Upvotes: 1

Related Questions