GNU Assembly Language - linux

Im trying to work on an assembly homework, but it seems that the cmp part is not working properly, it is not jumping to terminate even if my input is 6, can anyone help?
menu:
call display_menu
movl $3, %eax
movl $0, %ebx
movl $choice, %ecx
movl $2, %edx
int $0x80
##JE not working
cmp $6,(choice)
je _terminate
jmp menu
_terminate:
movl $1, %eax
movl $0, %ebx
int $0x80

Related

read data character by character from file in assembly GAS compiler

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

Segmentation fault cmovl

I get the error 'Segmentation fault (core dumped)' when trying to run some compiled assembly. The code that makes the program crash is the following:
.global tiny
.type tiny, #function
tiny:
pushl %ebp
movl %esp, %ebp
subl $16, %esp
# Compiling A1MINUS
movl $3, %eax
negl %eax
movl %eax, -4(%ebp)
# Compiling A0
movl -4(%ebp), %eax
movl %eax, -8(%ebp)
# Compiling A0
movl $7, %eax
movl %eax, -12(%ebp)
movl -8(%ebp), %eax
cmp %eax, -12(%ebp) // Error
movl $1, %eax // Error
movl %eax, %ebx //Error
movl $0, %eax //Error
cmovl %eax, %ebx // Error
movl %eax, -16(%ebp) // Error
# IF
movl -16(%ebp), %eax
cmp %eax , 0
jz lbl_3
movl -8(%ebp), %eax
pushl %eax
call print_int
addl $4, %esp
jmp lbl_4
lbl_3:
movl -12(%ebp), %eax
pushl %eax
call print_int
addl $4, %esp
lbl_4:
movl %ebp, %esp
popl %ebp
ret
I have no clue what my mistake is, any help is appreciated.
The wrong code (cmovl) is supposed to place a 0 or 1 in -16(%ebp), depending on the result of the comparison done by cmp. (the broken code is a translation of a 'lower then' statement).
As said in the comments, cmovl appearently can't make the code crash. Now I am even more clueless.
I am pretty sure the line cmp %eax, 0 causes the crash, because in at&t syntax the 0 there is a memory reference, a NULL pointer. Presumably you wanted to compare eax to 0, in which case you need cmp $0, %eax.
Learn to use a debugger.

Not sure how to flush buffer string x86

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

Getting ASCII number value

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.

Linux x86 assembly printing problems

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).

Resources