Newbie NASM question

Code junkies hangout here

Moderators: ChrisThornett, LXF moderators

Newbie NASM question

Postby pk_fox » Mon Apr 09, 2012 11:42 am

Hi all, I'm trying to write x number of lines to a text file using this code but it only writes 1 line ! any ideas as to what I am doing wrong


section .data
hello db 'Hello, world!',10 ; Our dear string
helloLen equ $ - hello ; Length of our dear string

section .bss
loopctr resd 1

section .text
global _start

_start:
mov dword [loopctr],10
pop ebx ; argc (argument count)
pop ebx ; argv[0] (argument 0, the program name)
pop ebx ; The first real arg, a filename

mov eax,8 ; The syscall number for creat() (we already have the filename in ebx)
mov ecx,00644Q ; Read/write permissions in octal (rw_rw_rw_)
int 80h ; Call the kernel
; Now we have a file descriptor in eax

test eax,eax ; Lets make sure the file descriptor is valid
js skipWrite ; If the file descriptor has the sign flag
; (which means it's less than 0) there was an oops,
; so skip the writing. Otherwise call the filewrite "procedure"
call fileWrite

skipWrite:
mov ebx,eax ; If there was an error, save the errno in ebx
mov eax,1 ; Put the exit syscall number in eax
int 80h ; Bail out

; proc fileWrite - write a string to a file
fileWrite:
mov ebx,eax ; sys_creat returned file descriptor into eax, now move into ebx
mov eax,4 ; sys_write
; ebx is already set up
mov ecx,hello ; We are putting the ADDRESS of hello in ecx
mov edx,helloLen ; This is the VALUE of helloLen because it's a constant (defined with equ)
jmp myloop

myloop:
dec dword [loopctr]
cmp dword [loopctr],0
je end
int 80h
jmp myloop


; endp fileWrite

end:
mov eax,6 ; sys_close (ebx already contains file descriptor)
int 80h
ret
User avatar
pk_fox
LXF regular
 
Posts: 298
Joined: Wed Apr 13, 2005 1:38 pm
Location: Surrey, UK

Postby SheamusPatt » Mon Apr 09, 2012 10:12 pm

Your problem is that a syscall, including 'write', returns a result in eax. So, you can't simply set the syscall number (in eax) and assume it's going to remain unchanged after the call, as you're doing in your write loop.

Set up the syscall number before each call in the 'myloop:' section, and it should work for you.
Sheamus
Ottawa, CANADA
SheamusPatt
 
Posts: 2
Joined: Mon Apr 09, 2012 10:04 pm
Location: Ottawa, Canada

Postby pk_fox » Tue Apr 10, 2012 6:09 am

Thanks Sheamus, I will give it a shot
User avatar
pk_fox
LXF regular
 
Posts: 298
Joined: Wed Apr 13, 2005 1:38 pm
Location: Surrey, UK

Postby pk_fox » Tue Apr 10, 2012 9:34 pm

SheamusPatt wrote:Your problem is that a syscall, including 'write', returns a result in eax. So, you can't simply set the syscall number (in eax) and assume it's going to remain unchanged after the call, as you're doing in your write loop.

Set up the syscall number before each call in the 'myloop:' section, and it should work for you.


Hi Sheamus, thanks for the help, I *pushed* eax before each sys call and *popped* it afterwards , worked perfectly ,- I am a pro dev but have never had to get messy with asm just interested after reading Mike Saunders article in LFormat - thanks again

Pete Kane
User avatar
pk_fox
LXF regular
 
Posts: 298
Joined: Wed Apr 13, 2005 1:38 pm
Location: Surrey, UK

Postby pk_fox » Thu Apr 12, 2012 11:28 am

Hi Sheamus, this is what I have now and it works fine, what I would like to do is add a line number to my output and can't for the life of me find a way of doing it ? any ideas as to how I can achieve this ?


section .data
hello db ' ) Hello, world!',10 ; Our dear string
helloLen equ $ - hello ; Length of our dear string

section .bss
loopctr resd 1
looplimit resd 1

section .text
global _start

_start:
mov dword [loopctr],0
mov dword [looplimit],1000
pop ebx ; argc (argument count)
pop ebx ; argv[0] (argument 0, the program name)
pop ebx ; The first real arg, a filename

mov eax,8 ; The syscall number for creat() (we already have the filename in ebx)
mov ecx,00644Q ; Read/write permissions in octal (rw_rw_rw_)
int 80h ; Call the kernel
; Now we have a file descriptor in eax

test eax,eax ; Lets make sure the file descriptor is valid
js skipWrite ; If the file descriptor has the sign flag
; (which means it's less than 0) there was an oops,
; so skip the writing. Otherwise call the filewrite "procedure"
call fileWrite

skipWrite:
mov ebx,eax ; If there was an error, save the errno in ebx
mov eax,1 ; Put the exit syscall number in eax
int 80h ; Bail out

; proc fileWrite - write a string to a file
fileWrite:
mov ebx,eax ; sys_creat returned file descriptor into eax, now move into ebx
mov eax,4 ; sys_write
; ebx is already set up
mov ecx,hello ; We are putting the ADDRESS of hello in ecx
mov edx,helloLen ; This is the VALUE of helloLen because it's a constant (defined with equ)
jmp myloop

myloop:
push eax
int 80h
pop eax
inc dword [loopctr]
push edx
mov edx,[loopctr]
cmp dword edx,[looplimit]
pop edx
je end
jmp myloop


; endp fileWrite

end:
mov eax,6 ; sys_close (ebx already contains file descriptor)
int 80h
ret
User avatar
pk_fox
LXF regular
 
Posts: 298
Joined: Wed Apr 13, 2005 1:38 pm
Location: Surrey, UK

Postby M-Saunders » Sat Apr 14, 2012 11:12 am

What do you mean by line number here -- ie referring to which file?

M
User avatar
M-Saunders
LXF regular
 
Posts: 2893
Joined: Mon Apr 11, 2005 12:14 pm

Postby pk_fox » Sat Apr 14, 2012 11:39 am

M-Saunders wrote:What do you mean by line number here -- ie referring to which file?

M


Hi Mike, sorry for not being clear. at the moment I write this string x times
' ) Hello, world!', what I would like to do is:

'1 ) Hello, world!'
' 2 ) Hello, world!'
'3 ) Hello, world!'
etc...

your tutorials started all this ;-) good fun though
User avatar
pk_fox
LXF regular
 
Posts: 298
Joined: Wed Apr 13, 2005 1:38 pm
Location: Surrey, UK

Postby M-Saunders » Sun Apr 15, 2012 10:03 pm

Ah. In that case you'll need a routine to convert a numeric value into its printable ASCII equivalent, and then print it. If you've got LXF156, the lib_print_number routine in library.asm does the trick. If not, I can post it here...

M
User avatar
M-Saunders
LXF regular
 
Posts: 2893
Joined: Mon Apr 11, 2005 12:14 pm

Postby pk_fox » Mon Apr 16, 2012 7:39 am

Thanks Mike , slight problem I've got the mag but not the dvd which has the code :-(
Last edited by pk_fox on Mon Apr 16, 2012 8:33 am, edited 1 time in total.
User avatar
pk_fox
LXF regular
 
Posts: 298
Joined: Wed Apr 13, 2005 1:38 pm
Location: Surrey, UK

Postby pk_fox » Mon Apr 16, 2012 8:32 am

M-Saunders wrote:Ah. In that case you'll need a routine to convert a numeric value into its printable ASCII equivalent, and then print it. If you've got LXF156, the lib_print_number routine in library.asm does the trick. If not, I can post it here...

M


Hi Mike, I downloaded the lib code and note that your routine prints to the screen and also adds a newline but I'm going to have a go modifying the code for my needs, thanks again and keep the helpline open :-)
User avatar
pk_fox
LXF regular
 
Posts: 298
Joined: Wed Apr 13, 2005 1:38 pm
Location: Surrey, UK

Postby pk_fox » Mon Apr 16, 2012 11:49 am

M-Saunders wrote:Ah. In that case you'll need a routine to convert a numeric value into its printable ASCII equivalent, and then print it. If you've got LXF156, the lib_print_number routine in library.asm does the trick. If not, I can post it here...

M


Hi Mike, tried using your print_number code with no success, If I'm reading it correctly your routine expects the number to be printed to be in eax, so I
*pushed eax* , *moved my value into eax* , called your routine then *popped eax* ; end result utter garbage in my output file :-( I am outputting to a file not the screen
User avatar
pk_fox
LXF regular
 
Posts: 298
Joined: Wed Apr 13, 2005 1:38 pm
Location: Surrey, UK

Postby M-Saunders » Mon Apr 16, 2012 12:18 pm

OK, you probably need to change the output stream. Put your current code into pastebin.com and I'll have a look at it!

M
User avatar
M-Saunders
LXF regular
 
Posts: 2893
Joined: Mon Apr 11, 2005 12:14 pm

Postby pk_fox » Tue Apr 17, 2012 8:59 am

M-Saunders wrote:OK, you probably need to change the output stream. Put your current code into pastebin.com and I'll have a look at it!

M


Hi Mike, never used pastebin before, I've put the code there and called it Code for Mike Saunders

Thanks again
User avatar
pk_fox
LXF regular
 
Posts: 298
Joined: Wed Apr 13, 2005 1:38 pm
Location: Surrey, UK

Postby M-Saunders » Wed Apr 18, 2012 12:32 pm

OK, here is a version with lib_print_number included from library.asm, and modified slightly to use the file descriptor. I've marked the additional lines with "XXX" in the comments:

http://pastebin.com/hNQjZE8R

This puts the number before each line in the file. Any questions, just shout!

M
User avatar
M-Saunders
LXF regular
 
Posts: 2893
Joined: Mon Apr 11, 2005 12:14 pm

Postby pk_fox » Wed Apr 18, 2012 1:50 pm

M-Saunders wrote:OK, here is a version with lib_print_number included from library.asm, and modified slightly to use the file descriptor. I've marked the additional lines with "XXX" in the comments:

http://pastebin.com/hNQjZE8R

This puts the number before each line in the file. Any questions, just shout!

M


Hi Mike, thanks very much for your help, one thing I notice is, if I change looplimit to 1000000 the last line in my output file is only 16959 ) Hello, world! - what do I need to change to use larger values ? also I would like to pass the limit as a parameter - is this possible ?
User avatar
pk_fox
LXF regular
 
Posts: 298
Joined: Wed Apr 13, 2005 1:38 pm
Location: Surrey, UK

Next

Return to Programming

Who is online

Users browsing this forum: Google [Bot] and 0 guests

cron