2016-02-28 6 views
2

Нам поручено выполнять сравнение целых значений и распечатать соответствующее приглашение, чтобы показать, какие значения больше.Сравнение целых значений в сборке

Код, указанный ниже, инициализирует «i» и «j» соответственно 5 и 4. Целью является сравнение «переменных» вместо самих значений . Таким образом, в этом примере, я ставлю 'I' и 'J' в имп, а не 5 и 4.

global _main 
extern _printf, _system 

section .text 


_main: 
; clear screen 
    push clr 
    call _system 
    add esp, 4 

;Test prints out i. Successfully does the job. 
    push dword [i]   ; why did it work here and not in *cmp*? 
    push prompt2 
    call _printf  
    add esp, 8 

;compare values and do a conditional jump. 
    CMP dword [i], dword [j]   ; compares values stored in i and j. i and j are base 10 nums. This is where the error appears. 
    JG igreat       ; jumps if i is greater than j. 
    JL jgreat       ; jumps if j is greater than i. 
    JE eks        ; jumps if i and j are equal. 
    ret         ; as a measure, this ends the code. 

    igreat:        ; prints out a prompt if i is greater than j. 
    push dword [j] 
    push dword [i] 
    push ibig 
    call _printf 
    add esp, 16 
    ret 

    jgreat:        ; prints out a prompt if j is greater than i. 
    push dword [i] 
    push dword [j] 
    push jbig 
    call _printf 
    add esp, 16 
    ret 

    eks:        ; prints out a prompt if i is equal to j. 
    push dword [i] 
    push dword [j] 
    push ex 
    call _printf 
    add esp, 16 
    ret 



last:         ; terminates the code 
ret 

section .data 
clr   db "cls",0    
i   dd 5      ; i is initialized to 5 
j   dd 4      ; j is initialized to 4 
prompt2  db "Value is %d",13,10,0 
ibig  db "Test 1. Comparisons: %d is bigger than %d",13,10,0 
jbig  db "Test 2. Comparisons: %d is bigger than %d",13,10,0 
ex   db "Test 3. Comparisons: %d is bigger than %d",13,10,0 

Два запросов я могу поднять:

  1. CMP DWORD [я], dword [j] создает ошибку: недопустимая комбинация кода операции и операндов; но я успешно восстановил значения, используя функции печати в предыдущем вызове/строках кода. Почему это?
  2. Я попытался заменить dword [j] с немедленным, скажем, мечом CMP [i], 9. Он распечатает правильное приглашение, но делает программу не отвечающей. Почему это?

Напоминаем, что я запускаю Windows 8 Intel 32 бит, этот код был «скомпилирован» в NASM, запущенном в DoSBox, и GCC в CMD.

Я новичок, и любая помощь будет высоко оценена. Спасибо!

+0

'ex' должен сказать,' equal'. – philipxy

+2

'CMP' может иметь только регистрацию и немедленную регистрацию, регистрацию, регистрацию и память или память и немедленно. Он не может сравнивать два расположения памяти, поэтому ошибка правильная. Что касается «не реагирования», я думаю, что ваш «ESP» сломан. Почему вы добавляете к нему 16? Почему бы не сохранить в «EBP» и восстановить в конце? –

ответ

6

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

Причина, по которой программа «не отвечает», связана с тем, что вы испортили ESP. Вы толкаете вещи в стек, звоните _printf, а затем по какой-то причине переместите ESP 16 байт вверх. RET затем перейдет к первому значению в стеке в этой точке, и я уверен, что это неверно.

Вы должны сохранить значение ESP в EBP при запуске и при возвращении восстановить ESP и затем RET.

+0

Я предполагаю, что проблема с ESP связана с смешиванием вызовов. – zx485

 Смежные вопросы

  • Нет связанных вопросов^_^