为什么cmp 2,2不等于0

时间:2013-03-12 22:23:35

标签: linux assembly nasm

extern putchar
extern exit
section .data

section .text
global main
main:

push 's'

mov eax, 2

cmp eax, 2

point:
call putchar
jz point

push 0
call exit

在控制台上,我只看到一个人的角色。

编译并运行

nasm -f elf ./prog.asm
gcc -m32 -o prog ./prog.o
./prog

2 个答案:

答案 0 :(得分:5)

cmp “等于0”(也就是说, 设置ZF标志)。但是,下一行中的call putchar会废弃由cmp设置的标记,因此您的jz无效(或多或少意外)。如果你想保存标志以供以后比较,你可以使用pushfpopf,但是这不会真的适用于你的情况,因为putchar会期望堆栈中的字符,不是旗帜。

现在,回答您未说明的实际问题。我假设你要打印's'两次。以下是如何正确地做到这一点:

  mov eax, 2 ; init counter

print_loop:
  push eax; save the counter since it will be trashed by putchar
  push 's'
  call putchar
  add esp, 4 ; restore the stack pointer since putchar is cdecl
  pop eax ; restore the saved counter
  dec eax ; decrement it
  jnz print_loop ; if it's not yet zero, do another loop

add esp, 4可以被另一个pop eax替换为更短的代码。

答案 1 :(得分:2)

执行cmp的结果是标志设置,zf为零,依此类推。然后,您可以分支是否设置了标记,或者使用set?指令之一来获取值,例如al寄存器,根据是否设置了标志进行设置。