带装配的表中元素的总和

时间:2018-10-31 00:21:31

标签: linux assembly sum

我不知道为什么我的程序没有显示卡住的元素之和的结果。它只显示字符串“ -----”

我正在使用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      

总和的结果必须显示在“ ------”消息之后

1 个答案:

答案 0 :(得分:3)

  

我不知道为什么我的程序不显示总和的结果

这是因为您实际上没有任何用于输出该代码的代码。您syscall-4输出----字符串,然后立即syscall-1退出。

如果您还想输出整数值,则需要一些代码来完成。尽管现代CPU具有推测性执行功能,但这并不意味着推测您真正想要执行的操作:-)

可能还想检查要加载到eax中的内容。这似乎是元素的数量,列表中有七个,但是您只处理前三个。毫无疑问,您会发现,一旦您成功输出了总和,但我想我还是会提到它。


根据修复问题所需的代码,我提供了一个小的实用程序功能,用于打印带符号的多头,并带有测试工具,以便您可以实际查看它。

测试工具是一个简单的bash脚本,它处理一系列测试数据项,然后将它们依次注入到实际的测试程序中:

#!/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

用于测试此代码的代码位于模板prog.in中,因此该测试工具可以对其进行处理以生成带有实际测试项目的代码。该文件包含:

.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

测试工具的特定运行的输出如下:

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')

关于需要添加到代码中的内容,除了最后的测试工具外,基本上就是一切。然后,您可以用一个简单的名称来调用它:

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