Pergunta

STORY(IM A NEWBIE): I started reading a pdf tutorial about programming in assembly(x86 intel) using the famous nasm assembler and i have a problem executing a very basic assembly code(inspired by a code about loops from the tutorial).

THE PROBLEM(JE FAILS): This assembly code should read a digit(a character(that means '0'+digit)) from stdin and then write to the screen digit times "Hello world\n".Really easy loop :decrease digit and if digit equals zero('0' not the integer the character) jump(je) to the exit(mov eax,1\nint 0x80).

Sounds really easy but when i try to execute the output is weird.(really weird and BIG) It runs many times throught the loop and stops when digit equals '0'(weird because until the program stops the condition digit == '0' been tested many times and it should be true)

Actually my problem is that the code fails to jump when digit == '0'

THE CODE(IS BIG):

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

THE OUTPUT:

Input a digit:4 4:Hello world 3:Hello world 2:Hello world 1:Hello world 0:Hello world ... ...(many loops later) ... 5:Hello world 4:Hello world 3:Hello world 2:Hello world 1:Hello world $

That is my question:What is wrong with this code? Could you explain that ? AND i dont need alternative codes that will magically(without explanation) run cause i try to learn(im a newbie)

That is my problem(and my first question in Stackoverflow.com )

Foi útil?

Solução

ECX is 32 bit, a character is just 8 bit. Use a 8 bit register, such as CL instead of ECX.

Outras dicas

As jester mentioned, ecx comes in as a character so you probably should use cl

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

You can also load ecx with movzx which clears the top bits of the register (i.e. a zero-extedning load):

  ...
  movzx ecx, byte [dig]
loop:
  mov [dig], cl           ; store just the low byte, if you want to store
  ...
  movzx ecx, byte [dig]
  dec ecx
  cmp ecx, '0'
  jne loop

Note that it is often suggested that you do not use the al, bl, cl, dl registers as their use is not fully optimized. Whether this is still true, I do not know.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top