linux - 表中元素的总和与汇编

标签 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      

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

最佳答案

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

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

如果您还想输出整数值,则需要一些代码来完成它。虽然现代 CPU 具有推测执行功能,但这并不意味着推测您真正想要做什么:-)

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


修复您的问题所需的代码而言,我提供了一个用于打印带符号长整型的小实用函数,以及一个测试工具,以便您可以看到它的实际情况。

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

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

关于linux - 表中元素的总和与汇编,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53074624/

相关文章:

linux - 如何放置我的脚本输出的特定路径?

assembly - 如何处理以字节为单位的数字

assembly - NES游戏开发: ASM6 tutorials?

java - 如何让管道命令也返回 Java exec 中的输出?

regex - sed regex - 当行中出现模式时匹配两个双引号之间的文本

assembly - 第一行是打印垃圾。无法识别错误

sql - 在 sql 的 case 语句中使用 sum 和 count

java - Java 中的复数求和函数

matlab - 将所有的 1 连续相加?

linux - 在 linux 中比较 2 个文件的不同单词