The goal of my code below to mimmic the cat program. It takes an input, and then spits it back out.
Such as:
$ Hi how are you
$ Hi how are you
$ good
$ good
What is happening though is:
$ Hi how are you
$ Hi how are you
$ good
$ good
$ow are you
My string is not being removed from my buffer and so if the input is shorter the second time, it will spit out the extra characters that have not been written over. I was wondering if anyone knew how to clear the buffer so this would not occur. Thanks
.file "rand.c"
.section .data
.buffer:
.space 10
.len:
.space 1
.globl _start
_start:
pushl %ebp
movl %esp, %ebp
andl $-16, %esp
subl $16, %esp
loop:
movl $3, %eax
movl $1, %ebx
movl $.buffer, %ecx
movl $100, %edx
int $0x80
movl $4, %eax
movl $1, %ebx
movl $.buffer, %ecx
movl $100, %edx
int $0x80
jmp loop
movl $1, %eax
movl $0, %ebx
int $0x80
Related
I'm writing an assembly program with GAS compiler and AT&T syntax.
I have 2 files: one to read from and another one to write in.
From terminal i launch the program in this way: ./myprogram inputfile.txt outputfile.txt
Now I want to read input data character by character and this is how I'm trying to do it:
.section .data
buff_size: .long 1
.section .bss
.lcomm buff, 18
.section .text # declaring our .text segment
.globl _start # telling where program execution should start
_start:
popl %eax # Get the number of arguments
popl %ebx # Get the program name
popl %ebx # Get the first actual argument - file to read
# open the file
movl $5, %eax # open
movl $0, %ecx # read-only mode
int $0x80
# read the file
movl $0, %esi
# these 6 instructions read first character from inputfile.txt
movl %eax, %ebx # file_descriptor,
movl $3, %eax
movl $buff, %edi
leal (%esi,%edi,1), %ecx
movl buff_size, %edx
int $0x80
# these 6 instructions can't read the second character from inputfile.txt and I can't understand why.
movl $1, %esi
movl $3, %eax
movl $buff, %edi
leal (%esi,%edi,1), %ecx
movl buff_size, %edx
int $0x80
# open the file
popl %ebx # Get the second actual argument - file to write
movl $5, %eax # open
movl $2, %ecx # read-only mode
int $0x80
# write to STDOUT
movl %eax, %ebx # file_descriptor
movl $4, %eax
leal buff, %ecx
movl buff_size, %edx
int $0x80
# exit
movl $1, %eax
movl $0, %ebx
int $0x80
This piece of code read the first character from inputfile.txt successfully and it writes that character inside outputfile.txt...
Now I want to read and write the second character but it doesn't work as suggested in the comment I've written through the code.
FYI:
OS: Ubuntu 14 - 64 bit
Compiler: GAS
My inputfile.txt looks so: 4,3,55,15,8,9
Hi Guys I got some annoying problem ,so I try to write a code just to reverse small string sequential
I Already got this :
.section .data
string:
.ascii "AAAAAABBBBBB"
length:
.quad . -string #Dot = 'here'
.section .text
.globl _start #Make entry point visible to linker
_start:
movl $4, %eax #4=write
movl $1, %ebx #1=stdout
movl $string, %ecx
movl length, %edx
int $0x80 #Call Operating System
movl length,%edi #counter
shrl $1,%edi #half of string
movl $0,%ecx #start from index one
movl length,%edx #start from end
reverse:
movl string(,%ecx,1),%eax
movl string(,%edx,1),%ebx
movl %eax,string(,%edx,1)
movl %ebx,string(,%ecx,1)
inc %ecx
dec %edx
dec %edi
loop reverse #looping
movl $4, %eax #4=write
movl $1, %ebx #1=stdout
movl $string, %ecx
movl length, %edx
int $0x80 #Call Operating System
movl $0, %ebx #Make program return syscall exit status
movl $1, %eax #1=exit
int $0x80 #Call System Again
And it's not working correctly , cuz in gbd i get wrong values in registers after making
movl string(,%ecx,1),%eax
or the next steps I think there should be in %eax value for A letter but its doesn't any ideas ?
Working at 64arch but emulating in as --32 so its problem with my addressing i guess
You should be processing bytes not longs, so use movb with 8 bit registers (al and bl, for example). Also, the LOOP instruction uses ECX automatically, you probably meant JNZ there to repeat until EDI reaches zero.
So guys I got problem . I'm trying just to change one letter in this easy string "Hello World"
so I'm trying assign value to memory cell like this
.section .text
string:
.ascii "Hello, world!"
length:
.quad . -string #Dot = 'here'
.globl _start #Make entry point visible to linker
_start:
movl $4, %eax #4=write
movl $1, %ebx #1=stdout
movl $string, %ecx
movl length, %edx
int $0x80 #Call Operating System
movl $98,4(%ecx) #Critical moment why cannot I do this?
movl $98,string(,%ebx,1) #cannot do this too ;(
movl $4, %eax #4=write
movl $1, %ebx #1=stdout
movl $string, %ecx
movl length, %edx
int $0x80
movl $0, %ebx #Make program return syscall exit status
movl $1, %eax #1=exit
int $0x80 #Call System Again
and additional info I'm working at x64(linux) and assembling it in emulation mode x32 by linux gas so should be all right , TY for replies
You have put your string into the .text section, which is read-only. You should put it into the .data section (but don't forget to switch back to .text for the program code).
I wrote this to print argv[0] in x86:
.section .data
newline: .int 0xa, 0
.section .text
.globl _start
_start:
sub %al, %al
movl 4(%esp), %edi /* Pointer to argv[0]. */
sub %ecx, %ecx /* Set %ecx to 0.*/
not %ecx /* Set %ecx to -1.*/
repne scasb /* Search for %al over and over.*/
not %ecx /* Set %ecx to |%ecx| - 1.*/
dec %ecx
movl %ecx, %edx /* Move the strlen of argv[0] into %edx.*/
movl $4, %eax
movl $1, %ebx
movl 4(%esp), %ecx
int $0x80
movl $newline, %ecx
movl $1, %edx
int $0x80
movl $1, %eax
movl $0, %ebx
int $0x80
When I run this file ("print"), the output is this:
[08:27 assembly]$ ./print test
./print[08:30 assembly]$
When I ran this through gdb, the actual string length held in edx is 27, and the string it's checking is "/home/robert/assembly/print", not "./print". So I changed the %esp offsets to 8, to check argv[1]. With the same command as before, the output is this:
test
[08:33 assembly]$
Why does checking argv[0] cause the strange output, when argv[1] does as expected?
I think gdb is "helping" you by adding the full path to argv[0]. After printing, %eax holds the number of characters printed, so you'll want to reload %eax for sys_write again to print the $newline (%ebx should still be okay) - by luck, "test" is the right length. Lord knows what system call you're getting with that longer string!
I'd say you're doing good! (might be a good idea to check argc to make sure argv[1] is there before you try to print it).
I wanna create a substring (ministring) of 3 asciz chars out of my original (thestring). The thing ain't printing when being run so I don't know what the hell I'm I doing. Why it ain't printing? Am I creating the ministring correctly?
.section .data
thestring: .asciz "111010101"
ministring: .asciz ""
formatd: .asciz "%d"
formats: .asciz "%s"
formatc: .asciz "%c"
.section .text
.globl _start
_start:
xorl %ecx, %ecx
ciclo:movb thestring(%ecx,1), %al
movzbl %al, %eax
movl %eax, ministring(%ecx,1)
incl %ecx
cmpl $3, %ecx
jl ciclo
movl thestring, %eax
pushl %eax
pushl $formats
call printf
addl $4, %esp
movl $1, %eax
movl $0, %ebx
int $0x80
You haven't reserved enough memory space to contain the null-terminated ministring which you're creating ... therefore, when you write to this memory, you're overwriting the value of formatd and formats (and so you're eventually passing something other than "%s" to printf).
Instead of your definition of the ministring memory location, try using the following :
ministring: .asciz " "
Also, instead of this:
movl %eax, ministring(%ecx,1)
I don't understand why you aren't using this instead:
movb %al, ministring(%ecx,1)
Also, if you want to print the ministring, then instead of this:
movl thestring, %eax
Do this:
movl ministring, %eax
Also instead of this:
addl $4, %esp
Why not this:
addl $8, %esp
ALso I suggest that you use a debugger to:
Step through the code
Watch the values contained in registers and in memory as you step through
Know the location of any segmentation fault