Author Topic: please find error in this  (Read 9235 times)

Offline tejaswi2195

  • Jr. Member
  • *
  • Posts: 9
please find error in this
« on: December 25, 2013, 04:03:14 PM »
i have attached a program which accepts n nos where n is entered by user.
program works properly in gdb whereas when i run it it accepts only half the nos
i couldn't understand what is wrong in the code
please help me.....


my code----->
Code: [Select]
%macro print 2
mov eax,4
mov ebx,1
mov ecx,%1
mov edx,%2
int 80h
%endmacro
%macro read 2
mov eax,3
mov ebx,0
mov ecx,%1
mov edx,%2
int 80h
%endmacro

SECTION .data
msg: db "enter count",10
len: equ $-msg
msg1: db "enter nos",10
len1: equ $-msg1

SECTION .bss
array: resb 10
count: resb 1

SECTION .text
global _start
_start:

print msg,len
read count,1
mov eax,[count]
sub eax,30h
mov edi,eax
ld:
print edi,1

print msg1,len1

mov esi,array

loop:
read esi,1

inc esi
dec edi
jnz loop

mov eax,1
mov ebx,0
int 80h
« Last Edit: December 25, 2013, 04:36:05 PM by Frank Kotler »

Offline Frank Kotler

  • NASM Developer
  • Hero Member
  • *****
  • Posts: 2667
  • Country: us
Re: please find error in this
« Reply #1 on: December 25, 2013, 05:35:55 PM »
This is apparently a very popular assignment lately! There are a couple of similar questions (in "example code") recently, which may also help you.

Code: [Select]
%macro print 2
mov eax,4
mov ebx,1
mov ecx,%1
mov edx,%2
int 80h
%endmacro
%macro read 2
mov eax,3
mov ebx,0
mov ecx,%1
mov edx,%2
int 80h
%endmacro

SECTION .data
msg: db "enter count",10
len: equ $-msg
msg1: db "enter nos",10
len1: equ $-msg1

SECTION .bss
array: resb 10
count: resb 1 ; one byte!

SECTION .text
global _start
_start:

print msg,len
read count,1
mov eax,[count]  ; move one byte -plus three garbage bytes - into eax
sub eax,30h  ; convert character to number
mov edi,eax  ; move the number to edi
ld:
print edi,1 ;  print one character from address "number" - unlikely to be valid memory

print msg1,len1

mov esi,array

loop:
read esi,1

inc esi
dec edi
jnz loop

mov eax,1
mov ebx,0
int 80h

sys_read, from stdin,  does not return until the "enter" key is hit. If the user types "1"(enter) (and edx is 1),  the "1"  goes into our buffer and the linefeed (0Ah) remains in the OS's input queue. On the next sys_read, the linefeed is read, no waiting, and goes in our buffer. This is why you're only accepting half of the expected number of numbers. I have no idea why it works in gdb.

Then you convert the character to a number, and try to use this number as the address of a buffer for sys_write. This simply isn't going to work - sys_write expects the address of a buffer in ecx, not some number to print.

I'll look at this in more detail later, but I think that's the essence of what's wrong with it.

Best,
Frank


Offline Mathi

  • Jr. Member
  • *
  • Posts: 82
  • Country: in
    • Win32NASM
Re: please find error in this
« Reply #2 on: December 26, 2013, 05:52:58 PM »
So, you need to accommodate the new line character also.
Even if the user enters a single digit , it would be two bytes including new line char.

So pass 2 instead of 1 for the number of chars.

like

Code: [Select]
%macro print 2
mov eax,4
mov ebx,1
mov ecx,%1
mov edx,%2
int 80h
%endmacro
%macro read 2
mov eax,3
mov ebx,0
mov ecx,%1
mov edx,%2
int 80h
%endmacro

SECTION .data
msg: db "enter count",10
len: equ $-msg
msg1: db "enter nos",10
len1: equ $-msg1

SECTION .bss
array: resb 10
count: resb 2 ; two bytes!

SECTION .text
global _start
_start:

print msg,len
read count,2
mov eax,[count]  ; move one byte -plus three garbage bytes - into eax
and eax,0xFF     ;; We are interested only in the last byte.
sub eax,30h  ; convert character to number
mov edi,eax  ; move the number to edi
ld:
print count,2 ;  sys_write (int 80h, eax=4)  requires an address of the buffer in ECX not actual number.
              ;  if you want to print a number you need to convert that to ascii string.

print msg1,len1

mov esi,array

L1:
read esi,2

inc esi
dec edi
jnz L1

mov eax,1
mov ebx,0
int 80h