Author Topic: Strange result after writing lines to file.  (Read 18374 times)

Offline Kleggas

  • Jr. Member
  • *
  • Posts: 3
Strange result after writing lines to file.
« on: June 24, 2010, 03:36:39 PM »
Hi all,

First of, I appologise if this question (or this kind) has been asked many times before. Tried to find a similar question but couldn't, so opening new thread.

I am new to assembler. Did some very old assembly at univ, not much at all, and have never used any assembly after that, private or professional. I work with Java, C and several other languages but have never had the "need" of optimizing with assembly. However, now I decided to learn it for fun :). And look, after 2 days of reading/trying/failing on doing several fun stuff/projects, I found this forum... it was just 1 google search away :D

My choice is NASM (on Slackware).

The problem (my latest problem/project):

I created a new file based upon the arg I provided to my program: ./myasm test.txt
Then I opened the file.
I wrote 5x lines to the file: "Line1",0xa - "Line5",0xa.
I then closed the file.
Exit program.

The result: ./cat test.txt
Line1
Line2
Line3
Line4
Line5
Line2
Line3
Line4
Line5
Line3
Line4
Line5
Line4
Line5
Line5

To me it seems that whats going on is it writes one line at time (int 0x80 between the writing, keeping file open at all time until done) and then it starts to "backing out" but from bottom, oldest entry removed first - rest written, until its all done.

Tried several "ugly hax" (without even knowing really what I tried) but nothing helped.

Solved with:

Open file
Write "Line1"
Close file

Open file
Write "Line2"
Close file... and so on.

Any input from the better knowing on what Im doing wrong? :)

Thanks - Curious second-day "asm-trier"

Offline Keith Kanios

  • Full Member
  • **
  • Posts: 383
  • Country: us
    • Personal Homepage
Re: Strange result after writing lines to file.
« Reply #1 on: June 24, 2010, 05:14:05 PM »
Any input from the better knowing on what Im doing wrong? :)

Sure, but the source code will help us give you a precise answer instead of a guess ;)

Offline Kleggas

  • Jr. Member
  • *
  • Posts: 3
Re: Strange result after writing lines to file.
« Reply #2 on: June 24, 2010, 05:43:08 PM »
Sure, why trying to explain the code when I can show the code :p

This is the original.

Code: [Select]
section .text
    global _start ;must be declared for linker (ld)

_start: ;tell linker entry point
pop ebx
pop ebx
pop ebx

mov eax,8 ;creat file with filename set in ebx
int 0x80

mov eax,5 ;open the file with filename still set in ebx
mov ecx,2 ;O_RDWR
int 0x80

mov ebx,eax ;get filepointer
mov edx,len1
mov ecx,line1
mov eax,4 ;write line1 to file with filepointer set in ebx
int 0x80

mov edx,len2
mov ecx,line2
mov eax,4 ;write line2 to file with filepointer set in ebx
int 0x80

mov edx,len3
mov ecx,line3
mov eax,4 ;write line3 to file with filepointer set in ebx
int 0x80

mov edx,len4
mov ecx,line4
mov eax,4 ;write line4 to file with filepointer set in ebx
int 0x80

mov edx,len5
mov ecx,line5
mov eax,4 ;write line5 to file with filepointer set in ebx
int 0x80

mov eax,6 ;close the file with filepointer set in ebx
int 0x80

mov eax,1 ;sysexit
mov ebx,0
int 0x80



section .data
line1 db 'Line1',0xa
line2 db 'Line2',0xa
line3 db 'Line3',0xa
line4 db 'Line4',0xa
line5 db 'Line5',0xa
len1 equ $ - line1
len2 equ $ - line2
len3 equ $ - line3
len4 equ $ - line4
len5 equ $ - line5

And this is how I solved it instead, by closing/opening file between the writing.

Code: [Select]
section .text
    global _start ;must be declared for linker (ld)

_start: ;tell linker entry point
pop ebx
pop ebx
pop ebx

mov eax,8 ;creat file with filename set in ebx
int 0x80

mov eax,5 ;open the file with filename still set in ebx
mov ecx,2 ;O_RDWR
int 0x80

mov ebx,eax ;get filepointer
mov edx,len1
mov ecx,line1
mov eax,4 ;write line1 to file with filepointer set in ebx
int 0x80

mov eax,6 ;close the file with filepointer set in ebx
int 0x80

mov eax,5 ;open the file with filename still set in ebx
mov ecx,2 ;O_RDWR
int 0x80

mov edx,len2
mov ecx,line2
mov eax,4 ;write line2 to file with filepointer set in ebx
int 0x80

mov eax,6 ;close the file with filepointer set in ebx
int 0x80

mov eax,5 ;open the file with filename still set in ebx
mov ecx,2 ;O_RDWR
int 0x80

mov edx,len3
mov ecx,line3
mov eax,4 ;write line3 to file with filepointer set in ebx
int 0x80

mov eax,6 ;close the file with filepointer set in ebx
int 0x80

mov eax,5 ;open the file with filename still set in ebx
mov ecx,2 ;O_RDWR
int 0x80

mov edx,len4
mov ecx,line4
mov eax,4 ;write line4 to file with filepointer set in ebx
int 0x80

mov eax,6 ;close the file with filepointer set in ebx
int 0x80

mov eax,5 ;open the file with filename still set in ebx
mov ecx,2 ;O_RDWR
int 0x80

mov edx,len5
mov ecx,line5
mov eax,4 ;write line5 to file with filepointer set in ebx
int 0x80

mov eax,6 ;close the file with filepointer set in ebx
int 0x80

mov eax,1 ;sysexit
mov ebx,0
int 0x80



section .data
line1 db 'Line1',0xa
line2 db 'Line2',0xa
line3 db 'Line3',0xa
line4 db 'Line4',0xa
line5 db 'Line5',0xa
len1 equ $ - line1
len2 equ $ - line2
len3 equ $ - line3
len4 equ $ - line4
len5 equ $ - line5

I compiled it with:
Code: [Select]
nasm -f elf myapp.asm
ld -s -o myapp myapp.o

Also, I have not set any permissions etc, seems I have to run it as root atm :)

Offline Frank Kotler

  • NASM Developer
  • Hero Member
  • *****
  • Posts: 2667
  • Country: us
Re: Strange result after writing lines to file.
« Reply #3 on: June 24, 2010, 09:40:35 PM »
Ah!

Code: [Select]
        line1 db 'Line1',0xa
line2 db 'Line2',0xa
line3 db 'Line3',0xa
line4 db 'Line4',0xa
line5 db 'Line5',0xa
len1 equ $ - line1
len2 equ $ - line2
len3 equ $ - line3
len4 equ $ - line4
len5 equ $ - line5

The '$' symbol (in this context) means approximately "here" - the current offset into the file - so "$ - line1" calculates the length of *all* your text. You need "len1" immediately after "line1", etc. for it to work. I suspected it must be something like that.

Not a bad way to do it, actually - print the whole thing with one sys_write... and then stop. Not very flexible, though. Ideally, I suppose you'd have just one "Line" as a literal, and calculate the number "on the fly" for as many lines as you need.

Running as root all the time is okay... if you're "careful". You can give the executable root permissions, even if the user isn't root, by doing (as root) something like:

Code: [Select]
chown root:root myfile
chmod +s myfile

Better yet would be to set the file permissions so you don't have to be root. I'm a little fuzzy how that works, but try "mov edx, 666q" ('q' is how Nasm indicates an octal number - 'o' or even 'O' will also work, but they look too much like zero for my taste!) Leaving edx "undefined" may not be a good idea.

Unless I'm mistaken, you can do "creat" and "open" in one shot, by "or"ing O_RDRW with O_CREAT (no 'E'!), and maybe "O_TRUNC" in ecx for the sys_open. (I'd have to look up the numbers for O_CREAT and O_TRUNC). In fact, I think you may be getting two file descriptors by doing both, but I'm not really sure.

There's a potential "bug" by not verifying that "argc" is 2 before proceeding. If the pesky user doesn't give a filename, I think it'll crash. It would be "polite" to print a "usage" message and exit cleanly. Personally, I consider a crash to be an emphatic, if non-verbose, error message, but it isn't the way we're "supposed" to do it. :)

I haven't tested your code, or "fiddled" with it, yet. I probably will - I learn a lot by playing with "other people's code"! I may be able to suggest other ways that it could be "improved".

To be able to get the filename from the command line, open it, and write anything at all is pretty good work for "day two", IMO! Keep at it and you'll go far!

Best,
Frank


Offline Kleggas

  • Jr. Member
  • *
  • Posts: 3
Re: Strange result after writing lines to file.
« Reply #4 on: June 24, 2010, 10:02:34 PM »
Wow, thanks a lot for that explanation and all the tips. They are ALL very helpful as I am still trying to learn the very basics of this thing called asm :)
I had no idea how the $ worked, and it was never explained in the places I read.

I tried asking in some irc channels, and immediatly I was mistaken for someone completely new to programming and got links to C, and Java etc..... things Ive been using for years and not the things I asked for at all.... asm != even close to any of those, knowing higher level languages is so different (in a way, in another its not) :)

I will be modifying and trying again, and play around a bit more. I will also try the permissions thingy, as of now my "ls -l" only shows ------- after building.

Again, thanks for the help.
« Last Edit: June 24, 2010, 10:04:18 PM by Kleggas »