JSecurity
JSecurity

Reputation: 195

Sum of elements in a table with assembly

I don't know why my program doesn't show the result of the sum of elements in the stuck. It just shows the string '-----'

I'm working on Linux.

.data 
#################################
tabEntier :   .long 3, 4, 2, 10, 16, 5, 6   #long = 4                     
maVar:  .space 4             

msgFin: .string "\n-----\n"
taillemsgFin = . - msgFin

################################
.text

.global _start 

_start:
movl $3, %eax          # eax ?
movl $0, %ebx          # ebx ?
movl $tabEntier, %ecx  # ecx ?

additionne:   
addl (%ecx), %ebx   # ebx  ?
    addl $4, %ecx       # ecx ?
    decl %eax           # eax ?
    jnz additionne       

stocke:
movl %ebx, maVar     

messageSortie:

movl $4, %eax        
movl $1, %ebx        
movl $msgFin,%ecx    
movl $taillemsgFin,%edx  
int $0x80        

sortie:  
movl $0, %ebx        
movl $1, %eax        
int $0x80      

The result of the sum must be shown after '------' message

Upvotes: 2

Views: 615

Answers (1)

paxdiablo
paxdiablo

Reputation: 882028

I don't know why my program don't show the result of the sum

It's because you don't actually have any code for outputting that. You syscall-4 to output the ---- string, then you immediately syscall-1 to exit.

If you want to output an integral value as well, you're going to need some code to do it. While modern CPUs have speculative execution, that doesn't mean speculating on what you really wanted to do :-)

You may also want to check what you're loading into eax. This seems to be the count of elements and there are seven in the list, but you only process the first three. No doubt you would have found that once you'd successfully output the sum but I thought I'd mention it anyway.


In terms of the code required to fix your issue, I include a small utility function for printing of signed longs, along with a test harness so that you can see it in action.

The test harness is a simple bash script which processes a series of test data items, injecting them in turn into the actual test program:

#!/bin/bash

# Selected test points, and some random ones.

testdata="0 1 -1 9 10 -9 -10 99 100 2147483647 -2147483648"
for i in {1..10} ; do
    testdata="${testdata} ${RANDOM} $((0 - ${RANDOM}))"
done

# Do each test item.

for item in ${testdata} ; do
    # Morph the asm template to create actual asm file,
    # then assemble and link.

    sed "s/XYZZY/${item}/" prog.in >prog.asm
    as --32 -o prog.o prog.asm
    ld -melf_i386 -o prog prog.o

    # Test that output is as expected.

    result="$(./prog)"
    if [[ "${item}" == "${result}" ]] ; then
        echo "Okay ('${item}')"
    else
        echo "BAD  ('${item}' -> '${result}'"
    fi
done

The code for testing this is in a template prog.in so it can be processed by that test harness to produce one with the actual test item. The file contains:

.data

numOut:     .string "2147483648"    # Largest signed-32 magnitude.
numEnd:
numLast=    numEnd - 1

negOut:     .string "-"             # Negative prefix.

# ======================================================================
# Actual function for output of signed long in EAX.

.text

outLong:    push    %eax            # Save registers.
            push    %ebx
            push    %ecx
            push    %edx

            cmpl    $0, %eax
            je      olZero          # Zero special case.

            jg      olPos           # Already positive.

            push    %eax            # Negative handled here.
            movl    $4, %eax        # SysWrite "-".
            movl    $1, %ebx
            movl    $negOut, %ecx
            movl    $1, %edx
            int     $0x80
            pop     %eax
            negl    %eax            # Then negate.

olPos:      movl    $numEnd, %ecx   # Last character placed.

olStore:    movl    $0, %edx        # eax = edx:eax / 10, remainder -> edx
            movl    $10, %ebx
            divl    %ebx

            addl    $'0', %edx      # Turn into ASCII and store.
            decl    %ecx
            movb    %dl, (%ecx)

            cmpl    $0, %eax        # Continue until zero.
            jnz     olStore

            jmp     olPrint

olZero:     movl    $numLast, %ecx  # Load 0 into buffer.
            movb    $'0', (%ecx)

olPrint:    movl    $4, %eax        # SysWrite call.
            movl    $1, %ebx        #   File descriptor 1.
            movl    $numLast, %edx  #   Calculate length.
            incl    %edx
            subl    %ecx, %edx
            int     $0x80           #   And print.

            pop     %edx            # Clean up and return.
            pop     %ecx
            pop     %ebx
            pop     %eax
            ret

# ======================================================================
# Test harness.

.global _start
_start:     movl    $XYZZY, %eax    # Load up test value.
            call    outLong

            movl    $1, %eax        # SysExit, success.
            movl    $0, %ebx
            int     $0x80

The output of one particular run of the test harness follows:

Okay ('0')
Okay ('1')
Okay ('-1')
Okay ('9')
Okay ('10')
Okay ('-9')
Okay ('-10')
Okay ('99')
Okay ('100')
Okay ('2147483647')
Okay ('-2147483648')
Okay ('3700')
Okay ('-30889')
Okay ('19074')
Okay ('-19825')
Okay ('22601')
Okay ('-19364')
Okay ('9291')
Okay ('-24785')
Okay ('28133')
Okay ('-2892')
Okay ('20544')
Okay ('-10782')
Okay ('20878')
Okay ('-28479')
Okay ('13808')
Okay ('-9415')
Okay ('17693')
Okay ('-6797')
Okay ('16385')
Okay ('-10299')

In terms of what you need to add to your code, it's basically everything except the test harness at the end. Then, you call it with a simple:

mov $42, %eax     # Load EAX however you desire.
call outLong      # And print it.

Upvotes: 4

Related Questions