I am trying to write an assembly program that take in a string from the file text.txt. Then the program encoded the string in ROT13 and using printf to display the result. However, It seem like i failed to read the file and get put in an infinite loop in "nextChar:" . I'm sure I miss something but not sure what it is.
Thank you
;%include "glibc"
section .data ;section declaration
getFmt: dd "%c",10,0
fileFmt: dd "%s",10,0
countFmt: dd "%d",10,0
output: dd "output.txt",10,0
writeCode: dd "w",10,0
readCode: dd "r",10,0
EOF: db -1 ;I read that this may need to be 0, instead of -1
Filename db "text.txt",0
section .bss
char:
buf: resb 1
section .text ;section declaration
global main
extern fopen
extern fclose
extern printf ;you can use this for debugging, otherwise not needed
extern getchar
extern putchar
extern scanf
main:
mov ebx, Filename ; push file name to ebx
push readCode ;set file to "read" mode
push ebx ;push file name
call fopen ;open file
add esp,8
cmp eax,0 ;see if file opened correctly
jne nextChar
ret
nextChar:
push ebx ; Push file handle on the stack
mov ebx,eax ; Save handle of opened file in ebx push ebx
push dword [char] ;get the next char from input file
push getFmt ;
call getchar ;use getchar function
add esp,12 ;clear the stack
cmp eax,0 ; A returned null indicates error or EOF
jle done ; If we get 0 in eax, close up & return
add dword [char],13 ;add 13 to the ASCII value
push dword [char] ; push to print
push getFmt ;
call printf ;use printf function
add esp, 8 ;clear the stack
jmp nextChar
done:
push ebx ; Push the handle of the file to be closed
call fclose ; Closes the file whose handle is on the stack
add esp,4 ; Clean up the stack
ret ; Go home
You have a loop that will be exited if getchar returns 0. If your file never has a zero byte in it this won't happen. Instead, getchar will continue to return EOF and your loop will go on indefinitely.
Check the value of EOF in your environment (usually -1, but always outside the range 0-255) and use that as the limiter for the loop.
Related
I so far have the code on how to basically ask the user for an input (csv) file and take the file and print out the data from a csv file. What I'm looking to do further with this program is take the printed out data and store it in a 2 dimensional array and print the information again.
BUFFER_SIZE = 50
.data
buffer BYTE BUFFER_SIZE DUP(?)
filename BYTE 80 DUP(0)
fileHandle HANDLE ?
.code
main PROC
; Let user input a filename.
mWrite "Enter an input filename: "
mov edx,OFFSET filename
mov ecx,SIZEOF filename
call ReadString
; Open the file for input.
mov edx,OFFSET filename
call OpenInputFile
mov fileHandle,eax
; Check for errors.
cmp eax,INVALID_HANDLE_VALUE ; error opening file?
jne file_ok ; no: skip
mWrite <"Cannot open file",0dh,0ah>
jmp quit ; and quit
file_ok:
; Read the file into a buffer.
mov edx,OFFSET buffer
mov ecx,BUFFER_SIZE
call ReadFromFile
jnc check_buffer_size ; error reading?
mWrite "Error reading file. " ; yes: show error message
call WriteWindowsMsg
jmp close_file
check_buffer_size:
cmp eax,BUFFER_SIZE ; buffer large enough?
jb buf_size_ok ; yes
mWrite <"Error: Buffer too small for the file",0dh,0ah>
jmp quit ; and quit
buf_size_ok:
mov buffer[eax],0 ; insert null terminator
mWrite "File size: "
call WriteDec ; display file size
call Crlf
; Display the buffer.
mWrite <"Buffer:",0dh,0ah,0dh,0ah>
mov edx,OFFSET buffer ; display the buffer
call WriteString
call Crlf
close_file:
mov eax,fileHandle
call CloseFile
quit:
exit
main ENDP
I am trying to use the strstr C function in a NASM assembly program but cannot seem to get it to print out correctly. I have tried multiple variations of this, but I think I may be misinterpreting how NASM returns the pointer value from C as I either get a blank line returned in the printf or a '(null)'. Could some help fill me in as why I cannot get the correct return value to be printed?
section .data
str1 db "Here is some text with a word",0x0A,0x00
str2 db "text",0x0A, 0x00
strFmt db "%s",0x0A,0x00
global _start
extern printf
extern strstr
section .text
_start:
push ebp
mov ebp, esi
push str2
push str1
call strstr
add esp, 8
mov dword [myString], eax
push dword [myString]
push strFmt
call printf
add esp, 8
_exit:
mov ebx, 0
mov eax, 1
int 0x80
The main issue is the 0x0A in the search string. It's a part of the string, as everything before the terminating null is a part of it. It must be listed separately because C-style escape sequences inside strings won't be resolved by the assembler. A "test\n" won't be found by strstr. Remove the 0x0A and strstr will found the search string.
As Cody Gray mentioned, the block with mov ebp, esi is strange—you probably meant the idiomatic mov ebp, esp. Moreover, it's not needed in this example. Also superfluous is the indirection with myString—just push eax directly.
printf writes the output first to a buffer. You exit the program with a int 80h system call. This call will destroy everything of the process including the printf-buffer. So the buffer won't be outputted. There are two ways to solve the problem:
1) Use the C function exit instead of the system call:
section .data
str1 db "Here is some text with a word",0x0A,0x00
str2 db "text",0x00
strFmt db "%s",0x0A,0x00
global _start
extern printf, strstr, exit
section .text
_start:
push str2
push str1
call strstr
add esp, 8
push eax
push strFmt
call printf
add esp, 8
_exit:
push 0
call exit
2) Add a call to the C function fflush:
section .data
str1 db "Here is some text with a word",0x0A,0x00
str2 db "text",0x00
strFmt db "%s",0x0A,0x00
global _start
extern printf, strstr, fflush
section .text
_start:
push str2
push str1
call strstr
add esp, 8
push eax
push strFmt
call printf
add esp, 8
push 0
call fflush
_exit:
mov ebx, 0
mov eax, 1
int 0x80
I need to make a program that open a file, read it character by character and save it into an array in Assembly NASM x86. Currently, the program is able to open a file using stdin and read the character by using getchar(). However, i am stuck on the saving the char into an array and need help on this part.
Thank you
; Run it this way:
; test < (input file)
; Build using these commands:
; nasm -f elf -g -F stabs test.asm
; gcc –m32 -o test.o test
;
SECTION .bss ; Section containing uninitialized data
TextLenght EQU 1024 ; Define length of a line of text data
Text resb TextLenght ; Define array
SECTION .data ; Section containing initialised data
fileFmt: db "%c",0
SECTION .text ; Section containing code
extern putchar
extern getchar
extern printf
global main; Linker needs this to find the entry point!
main :
start:
nop ; This no-op keeps gdb happy...
mov eax, 0
mov edx, 0
mov ecx, 0
mov ebx, 0
; Read a buffer full of text from stdin:
read:
call getchar ; call getchar to get input from stdin, char is save in eax
cmp al, -1
jle Done ; if return -1, we at EOF
cmp eax, 97 ; get rid of 'enter' char
jl read
;mov Text, eax; try to save char in eax into array, don;t work
push eax ;push eax to print
push fileFmt
call printf
add esp, 8 ; clear the stack
jmp read
Done:
mov eax,1 ; Code for Exit Syscall
mov ebx,0 ; Return a code of zero
int 80H ; Make sys_exit kernel call
I'm new in assembly programming and I have an assignment in which I have to read a text file line by line and use what is written in the file and pass it to another function. My problem is that I'm not sure of how to read the text this way because from what I have discovered for reading a text file first I have to create a buffer reserving certain quantity of bytes for storing what is in the file. Howerver in this case I want to read line by line (like a loop) until the end of file so I dont know how much bytes I have to reserve. Thanks.
Btw here is the code I'm trying to use:
SECTION .data
file_name db 'instruct.txt',0
SECTION .bss
fd_out resb 1
fd_in resb 1
info resb 20
SECTION .text
global main
main: ;tell linker entry point
push ebp
mov ebp, esp
push ebx
;open the file for reading
mov eax, 5
mov ebx, file_name
mov ecx, 2
mov edx, 0777 ;read, write and execute by all
int 0x80
mov [fd_in], eax
loop:
;read from file
mov eax, 3
mov ebx, [fd_in]
mov ecx, info
mov edx, 5
int 0x80
cmp eax, 0
;check EOF
je exit
; print the info
mov eax, 4
mov ebx, 1
mov ecx, info
mov edx, 5
int 0x80
;
jmp loop
mov eax,1 ;system call number (sys_exit)
int 0x80 ;call kernel
exit:
; close the file
mov eax, 6
mov ebx, [fd_in]
pop ebx
mov esp, ebp
pop ebp
ret
use mmap syscall, read entire file to memory and search for 0x0A sequence. This is the ASCII code for end of line. Perhaps usefull too to check for 0x0D (in case you are dealing with windows text files. There the sequence 0x0A,0x0D indicates an new line and thus an end of line.
mmap will try to allocate memory for you without the overhead of administration for you. Otherwise determine the file length and reserve memory with syscall sbrk. Works also but you have to program a bit more. My suggestion is that mmap is the best way.
hey im a beginner in assembly ,, i wont to open a file and read value " integer "
from it and save the integer in buffer to print on the screen this is my code it doesn't work
include inout.asm
.model small,c
.486
.stack
.data
org 100h ; .com memory layout
buf db ?
file db "c:\rtasm\bin\file.txt";the file name in bin
.code
mov dx, offset file ; address of file to dx
mov al,0 ; open file (read-only)
mov ah,3dh
int 21h ; call the interupt
mov bx,ax ; put handler to file in bx
mov ah,40h
mov bx,ax
mov cx,2h ;; how many bytes you want to read
mov dx,offset buf ;; where you want to store that data (see note on Offset above)
int 21h
call putchar,offset buf; print char on the screen
mov ah,3eh
mov bx,ax
int 21h
.exit
END
Int 21h function 3Dh ("OPEN EXISTING FILE") expects a zero-terminated string in ds:dx. The string you're supplying doesn't have a zero terminator. The filename should be declared as file db "c:\rtasm\bin\file.txt",0.
Both function 3Dh and 40h return error codes if they fail. You should check for these and inform the user (yourself in this case) if an error has occurred, rather than assuming that the operations always will succeed.
Another problem is the following code:
mov bx,ax ; put handler to file in bx
mov ah,40h
mov bx,ax <-- gives you a nonsense file handle since ah now is 40h
mov cx,2h ;; how many bytes you want to read
mov dx,offset buf ;; where you want to store that data (see note on Offset above)
int 21h
The second mov bx,ax is unnecessary since bx already contains the file handle. In fact, it's not only unnecessary but also incorrect since you've overwritten the high part of ax (ah) with the value 40h.
There's also the fact that you're reading two bytes into a buffer that only has room for one byte.