【问题标题】:Comparing integer values in assembly比较汇编中的整数值
【发布时间】:2016-02-28 08:36:00
【问题描述】:

我们的任务是比较整数值并打印出适当的提示以显示哪些值更大。

我在下面编写的代码分别将“i”和“j”初始化为 5 和 4。目的是比较“变量”而不是 立即 值本身。所以在这个例子中,我把 'i' 和 'j' 放在 cmp 中,而不是 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 [i], dword [j] 产生错误:操作码和操作数的组合无效;但我成功地使用 printf 在前面的调用/代码行上运行。这是为什么呢?
  2. 我尝试将 dword [j] 替换为立即数,例如 CMP dword [i], 9。它确实打印出正确的提示,但使程序没有响应。这是为什么呢?

请注意,我正在运行 Windows 8 Intel 32 位,此代码已在 DoSBox 中运行的 NASM 和 CMD 中的 GCC 中“编译”。

我是一个完全的初学者,任何帮助将不胜感激。谢谢!

【问题讨论】:

  • ex 应该说,equal
  • CMP 只能有寄存器和立即数、寄存器和寄存器、寄存器和内存或内存和立即数。它无法比较两个内存位置,因此错误是正确的。至于“没有回应”,我认为你的 ESP 坏了。为什么要加16?为什么不存入EBP,最后恢复呢?

标签: assembly integer compare intel cmp


【解决方案1】:

CMP 无法比较两个内存位置。它可以将寄存器与寄存器、常量或内存进行比较,并且可以将内存位置与常量或寄存器进行比较。这就是为什么你得到一个错误并且它是正确的。您必须将其中一个的值存储到寄存器中,然后进行比较。

程序“没有响应”的原因是你搞砸了ESP。你将东西压入堆栈,调用_printf,然后出于某种原因将ESP 向上移动16 个字节。然后RET 将跳转到堆栈中的第一个值,我确定它不正确。

您应该在启动时将ESP 值存储到EBP 中,并在返回时存储ESP 然后RET

【讨论】:

  • 我猜想 ESP 的问题是由于调用约定的混合造成的。
猜你喜欢
  • 1970-01-01
  • 2010-11-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-05-24
  • 2022-01-14
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多