pgubook-readers
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Pgubook-readers] Chapt 5 - Heynow Create Files Exercise


From: Mark Schmid
Subject: [Pgubook-readers] Chapt 5 - Heynow Create Files Exercise
Date: Mon, 24 Sep 2007 12:27:39 +0200

Here's another question that probably
won't get answered:

In chapter 5 it says to try and write a program
that creates a file called "heynow.txt" which has
the words "Hey diddle, diddle!" inside it.

I did that, but for some reason unlike the file
created by the "toupper" program, the file
"heynow.txt" is not properly displayed in Linux
when using "cat".
Doing "cat heynow.txt" just gives you the prompt again.
If I do "cat outputfileoftoupper", it prints the
text of the output file of the "toupper" program.

I took a look at the contents of "heynow.txt" with
vi, which displays a bunch of numbers, seemingly
the ASCII codes of the text I wrote, on the right
side then I can see the text "Hey diddle, diddle!".

If I open the file in pico or with notepad in Windows,
I see the text displayed correctly, just not with
"cat" on Linux. Why is this? What's the difference
in the file I created with the toupper program and
the following one:
-----------------------
########################################################################
###             heynow.s - Create "heynow.txt" file.                 ###
########################################################################
# PURPOSE:      This program creates a file with the name "heynow.txt"
#               which contains the text "Hey diddle diddle!".
#
# REGISTERS:    %esi - Used to hold the current memory address
#                      of the next byte of filetext to write.
#                      (Initialized with $filetext, then 
#                      $STRING_ELEMENT_SIZE is added in every loop
#                      pass.
#               %edi - Used as current offset from starting memory
#                      address of filetext.


########################################################################
.section .data

############# CONSTANTS ################
# System Call Numbers:
.equ SYS_OPEN, 5
.equ SYS_WRITE, 4
.equ SYS_READ, 3
.equ SYS_CLOSE, 6
.equ SYS_EXIT, 1

# Options for open (look at /usr/include/asm/fcntl.h for various
# values. - You can combine them by ADDing them or ORing them.)
.equ O_RDONLY, 0
.equ O_CREAT_WRONGLY_TRUNC, 03101

# Some standard file descriptors (perhaps not needed):
.equ STDIN, 0
.equ STDOUT, 1
.equ STDERR, 2

# System call interrupt:
.equ LINUX_SYSCALL, 0x80

# End of string marker:
.equ END_OF_STRING, 0


# Define beginning of 'filename' label here:
filename:
.byte 'h','e','y','n','o','w','.','t','x','t',0
# Should be same as: .ascii "heynow.txt\0"

# Define beginning of 'filetext' label here:
filetext:
.byte 'H','e','y',',','d','i','d','d','l','e',' ','d','i','d','d','l','e','!',0
# Should be same as: .ascii "Hey diddle diddle!\0"

# Define STRING_ELEMENT_SIZE as used above:
.equ STRING_ELEMENT_SIZE, 1     # Byte, Ascii = 1, Int = 2, Long = 4


########################################################################
.section .bss

# Reserve space for output file descriptor:
.equ FILE_DESCRIPTOR_SIZE, 4
.lcomm FILE_DESCRIPTOR_OUT, FILE_DESCRIPTOR_SIZE



########################################################################
.section .text

.globl _start
_start:

### OPEN OUTPUT FILE: ###
# Open System call must be in %eax:
movl $SYS_OPEN, %eax
# Pointer to output file name must be in %ebx:
# (filename = first byte at filename = 'h', $filename = actual
# address number of first byte of filename = POINTER)
movl $filename, %ebx
# Flags for writing to the file must be in %ecx:
movl $O_CREAT_WRONGLY_TRUNC, %ecx
# Permission set for new file (if it's created) must be in %edx:
movl $0666, %edx
# Make system call to Linux:
int $LINUX_SYSCALL

# Store File Descriptor of output file returned by 
# Linux system call in %eax:
movl %eax, FILE_DESCRIPTOR_OUT



# Set filetext index counter %edi needed in this loop to 0:
movl $0, %edi

# Store first memory address of filetext in %esi so we can
# add the filetext index counter to that to iterate through
# the memory addresses of filetext:
movl $filetext, %esi

### BEGIN BYTE WRITING LOOP ###
byte_writing_loop_begin:

 # See if we've reached the end of the string yet:
 cmpl $END_OF_STRING, filetext(,%edi,STRING_ELEMENT_SIZE)
 # If found or on error, go to end:
 jle byte_writing_loop_end
 
 ### WRITE SINGLE BYTE TO THE OUTPUT FILE ###
 # Move the WRITE System Call number into %eax:
 movl $SYS_WRITE, %eax
 # Move the Pointer of the output File Descriptor into %ebx:
 movl FILE_DESCRIPTOR_OUT, %ebx
 # Move the beginning memory address of the buffer to write
 # (that's $filetext + $STRING_ELEMENT_SIZE in %esi) into %ecx:
 movl %esi,%ecx
 # Move the size of the buffer being written into %edx:
 movl $STRING_ELEMENT_SIZE, %edx
 # Make the sytem call to write this to the output file descriptor:
 int $LINUX_SYSCALL
 
 # Add the STRING_ELEMENT_SIZE to the starting memory address
 # of filetext (=$filetext) (stored in %esi) and store that in 
 # %esi:
 addl $STRING_ELEMENT_SIZE, %esi 

 # Increase index counter %edi:
 incl %edi
 
 # Jump back to beginning of loop:
 jmp byte_writing_loop_begin
 
byte_writing_loop_end:
### END BYTE WRITING LOOP ###

### CLOSE OUTPUT FILE: ###
# Move the close file system call number into %eax:
movl $SYS_CLOSE, %eax
# Move the pointer to the output File Descriptor into %ebx:
movl FILE_DESCRIPTOR_OUT, %ebx
# Make the system call to Linux:
int $LINUX_SYSCALL

### EXIT PROGRAM ###
# Move the exit system call number into %eax:
movl $SYS_EXIT, %eax
# Move the return status $0 into %ebx:
movl $0, %ebx
# Make the system call to Linux:
int $LINUX_SYSCALL

---------------------------------------------------

Anyone have an idea?

Greetings,
Mark

-- 
Psssst! Schon vom neuen GMX MultiMessenger gehört?
Der kanns mit allen: http://www.gmx.net/de/go/multimessenger




reply via email to

[Prev in Thread] Current Thread [Next in Thread]