linux x86 intel语法(NASM)中的条件跳转失败

时间:2014-03-11 13:03:28

标签: linux assembly nasm intel-syntax

故事(IM A NEWBIE): 我开始使用着名的nasm汇编程序阅读有关汇编(x86 intel)编程的pdf教程,我在执行一个非常基本的汇编代码时遇到了问题(灵感来自教程中循环的代码)。

问题(JE FAILS): 这个汇编代码应该从stdin读取一个数字(一个字符(表示'0'+数字))然后写入屏幕数字乘以“Hello world \ n”。真的很容易循环:减少数字,如果数字等于零(' 0'不是字符的整数)跳转(je)到出口(mov eax,1 \ nint 0x80)。

听起来很简单但是当我尝试执行输出时很奇怪。(真的很奇怪和大) 它在循环中运行多次并在数字等于'0'时停止(很奇怪,因为直到程序停止条件数字=='0'已经多次测试并且它应该是真的)

实际上我的问题是当数字=='0'

时代码无法跳转

代码(很大)

segment .text
global _start
_start:

;Print 'Input a digit:'.
mov eax,4
mov ebx,1
mov ecx,msg1
mov edx,len1
int 0x80

;Input the digit.
mov eax,3
mov ebx,0
mov ecx,dig
mov edx,2
int 0x80

;Mov the first byte(the digit) in the ecx register.
;mov ecx,0
mov ecx,[dig]

;Use ecx to loop dig[0]-'0' times.
loop:

mov [dig],ecx

mov eax,4
mov ebx,1
mov ecx,dig
mov edx,1
int 0x80

mov eax,4
mov ebx,1
mov ecx,Hello
mov edx,Hellolen
int 0x80

;For some debuging (make the loop stop until return pressed)
;mov eax,3
;mov ebx,0
;mov ecx,some
;mov edx,2
;int 0x80

;Just move dig[0](some like character '4' or '7') to ecx register and compare ecx with character '0'.
mov ecx,[dig]
dec ecx
cmp ecx,'0'

;If comparison says ecx and '0' are equal jump to exit(to end the loop)
je exit

;If not jump back to loop
jmp loop

;Other stuff ...(like an exit procedure and a data(data,bss) segment)
exit:
mov eax,1
int 0x80

segment .data
msg1 db "Input a digit:"
len1 equ $-msg1

Hello db ":Hello world",0xa
Hellolen equ $-Hello

segment .bss
dig resb 2
some resb 2

输出

输入一个数字:4 4:你好世界 3:你好世界 2:你好世界 1:你好世界 0:你好世界 ... ......(以后有很多循环) ... 5:你好世界 4:你好世界 3:你好世界 2:你好世界 1:你好世界 $

这是我的问题:这段代码有什么问题? 你能解释一下吗? 并且我不需要替代代码将神奇地(没有解释)运行因为我尝试学习(即时通讯新手)

这是我的问题(以及我在Stackoverflow.com中的第一个问题

2 个答案:

答案 0 :(得分:0)

ECX是32位,一个字符只是8位。使用8位寄存器,例如CL而不是ECX

答案 1 :(得分:0)

正如小丑提到的那样,ecx作为一个角色出现,所以你可能应该使用cl

loop:
  mov [dig],cl
  ...
  mov cl,[dig]
  dec cl
  cmp cl,'0'
  jne loop

您还可以使用movz加载ecx,它会清除寄存器的顶部位:

  ...
  movz ecx,byte:[dig]
loop:
  mov [dig],ecx    ; this works because Intel are little endian (in most cases)
  ...
  mov ecx,[dig]
  dec ecx
  cmp ecx,'0'
  jne loop

请注意,通常建议您不要使用al,bl,cl,dl寄存器,因为它们的使用尚未完全优化。这是否仍然是真的,我不知道。