Я не знаю, почему моя программа не показывает результат суммы
Это потому, что у вас на самом деле нет кода для его вывода. Вы syscall-4
выводите строку ----
, а затем немедленно syscall-1
для выхода.
Если вы хотите также вывести целочисленное значение, вам понадобится некоторый код для этого. В то время как современные процессоры имеют спекулятивное выполнение, это не означает, что вы действительно хотели бы сделать : -)
Вы можете также хотите проверить, что вы загружаете в 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.