Сумма элементов в стеке с использованием push и pop

Моя программа не работает, я хочу просуммировать элементы, находящиеся в стеке. Я собрал числа в стеке и затем хочу их суммировать, восстанавливая их из стека и вставляя результат в регистр eax.

.code32

#######################################
.data
msgFin:   .string "\n-----\n"
sizeMsg = . - msgFin

msgA: .string "addition\n"
sizemsgA = . - msgA

number:   .long 0

#######################################
.bss

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

.global _start

_start:   
andl $0, %eax

initialisePile:
push %ebp
movl %esp, %ebp

empile:
movl $1, %edx
push %edx
movl $2, %edx
push %edx
movl $3, %edx
push %edx
movl $4, %edx
push %edx
movl $5, %edx
push %edx

showAddition:
movl $msgA, %ecx 
movl $4, %eax 
movl $1, %ebx 
movl $sizemsgA,%edx 
int $0x80

additionStack:
pop %edx
addl %edx,%eax
cmpl %esp,%ebp
je exit
jmp additionStack

exit:
movl $4, %eax 
movl $1, %ebx 
movl $msgFin,%ecx  
movl $sizeMsg,%edx 
int $0x80

show result:
movl %eax,$number
movl $number,%ecx
movl $4, %eax 
movl $1, %ebx 
int $0x80

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

Я не знаю, почему моя программа не показывает результат суммы застрявших элементов.

Заранее спасибо.

Вы мысленно следили за ходом своей программы? Мне это кажется неправильным. Можете ли вы объяснить каждый блок, чтобы мы могли лучше его понять?

Margaret Bloom 31.10.2018 11:42

Вы можете упростить с push $1. Вам не нужно сначала переходить в EDX. И вместо je exit / jmp top_of_loop вы можете просто jne top_of_loop, чтобы сделать обычный asm-цикл в стиле do{}while().

Peter Cordes 31.10.2018 11:48

Помимо вероятного получения ожидаемого результата 15 = 0FH из-за того, что аккумулятор не очищается перед addStack, двоичное значение в% eax необходимо преобразовать в строку ASCII.

Shift_Left 31.10.2018 17:27
1
3
160
1

Ответы 1

I don't know why my program don't show the result of the sum of elements in the stuck.

Ряд причин:

  • Вы слишком рано опорожняете аккумулятор %eax в коде! Ваша инструкция andl $0, %eax должна идти прямо перед циклом, в котором вы фактически выполняете добавления. Как вы это написали, регистр тем временем использовался для чего-то другого. (Призыв показать первое сообщение movl $4, %eax).

  • Вы теряете результат добавления, потому что регистр %eax повреждается при вызове отображения второго сообщения! Инструкция movl %eax,$number находится непосредственно под циклом сложения.

  • Чтобы показать полученное число, вы использовали ту же функцию api, которую вы использовали для отображения текстовых сообщений. Регистр %ecx содержит адрес, а регистр %edx - размер. Но этот код:

    show result:
    movl %eax,$number    <- Binary form
    movl $number,%ecx
    movl $4, %eax 
    movl $1, %ebx 
    int $0x80
    

    не помещает адрес текстового представления результата в %ecx и не определяет размер %edx. Инструкция movl %eax,$number сохраняет только двоичное представление результата. Либо используйте функцию api, которая может выводить числовое значение, либо самостоятельно конвертируйте число в текст.


Ваш код с небольшими исправлениями добавлен:

_start:   

initialisePile:
  push %ebp
  movl %esp, %ebp

empile:
  push $1
  push $2
  push $3
  push $4
  push $5

showAddition:
  movl $msgA, %ecx 
  movl $4, %eax 
  movl $1, %ebx 
  movl $sizemsgA,%edx 
  int  $0x80

  xorl %eax, %eax    ; better than 'andl $0, %eax'
additionStack:
  pop  %edx
  addl %edx,%eax
  cmpl %esp,%ebp
  jne  additionStack
  movl %eax,$number  ; don't loose the sum

exit:
  movl $4, %eax 
  movl $1, %ebx 
  movl $msgFin,%ecx  
  movl $sizeMsg,%edx 
  int  $0x80

; Here you decide how you want to show the n u m b e r!

Другие вопросы по теме