I have the following assembly code down here. Basically I want to execute sys_write syscall twice to write something to stdout.
section .text
global _start
_start:
;write hello world
mov eax, 4
mov ebx, 1
mov edx, len_hello_world
mov ecx, hello_world
int 0x80
;write my name
mov eax, 4
mov ebx, 1
mov edx, len_my_name
mov ecx, my_name
int 0x80
;exit program
mov eax, 1 ; sys_exit
int 0x80
section .data
hello_world db "Hello, World!", 0xd
len_hello_world equ $ - hello_world
my_name db " My name is Moritz!", 0x13
len_my_name equ $ - my_name
Expected output:
Hello, World! My name is Moritz!
Actual output:
My name is Moritz!
My question is: Why is the first sys_call "skipped" (sorry for layman terms, i'm total noob)
Related
I am supposed to write a small assembly "program" that simply reads a file using a loop and outputs the contents to STDOUT.
Now, I made a program that can read the file and unfortunately only outputs the first line. I also can't figure out how to use the loop.
This is my very first time working with assembly and I do it because I have to, not because I want to.
Here's my code:
section .text
global _start ;must be declared for using gcc
_start: ;tell linker entry point
;open the file for reading
mov eax, 5
mov ebx, file_name
mov ecx, 0 ;for read only access
mov edx, 0777 ;read, write and execute by all
int 0x80
mov [fd_in], eax
;read from file
mov eax, 3
mov ebx, [fd_in]
mov ecx, info
mov edx, 26
int 0x80
; close the file
mov eax, 6
mov ebx, [fd_in]
; print the info
mov eax, 4
mov ebx, 1
mov ecx, info
mov edx, 26
int 0x80
mov eax,1 ;system call number (sys_exit)
int 0x80 ;call kernel
section .data
file_name db './passwd'
section .bss
fd_out resb 1
fd_in resb 1
info resb 26
I am currently learning the ASM, I have a question about the following code (which compiles)
This code come from this tutorial.
The question is: Why do I have the same behaviour when the fd is egual to 0, 1 or 2 (corresponding to stdin, stdout and stderr), at the indicated line, and when the fd is egual to 3 or more, it does nothing (it skips the scanf).
section .data ;Data segment
userMsg db 'Please enter a number: ' ;Ask the user to enter a number
lenUserMsg equ $-userMsg ;The length of the message
dispMsg db 'You have entered: '
lenDispMsg equ $-dispMsg
section .bss ;Uninitialized data
num resb 5
section .text ;Code Segment
global _start
_start: ;User prompt
mov eax, 4
mov ebx, 1
mov ecx, userMsg
mov edx, lenUserMsg
int 80h
;Read and store the user input
mov eax, 3
mov ebx, 2 ; /!\ QUESTION IS ABOUT THIS LINE /!\
mov ecx, num
mov edx, 5 ;5 bytes (numeric, 1 for sign) of that information
int 80h
;Output the message 'The entered number is: '
mov eax, 4
mov ebx, 1
mov ecx, dispMsg
mov edx, lenDispMsg
int 80h
;Output the number entered
mov eax, 4
mov ebx, 1
mov ecx, num
mov edx, 5
int 80h
; Exit code
mov eax, 1
mov ebx, 0
int 80h
We can compile and execute this code with the following command:
$> nasm -f elf64 test.S
$> ld test.o
$> ./a.out
Thank you,
I'm trying to study assembly, while trying out the example in the tutorials I get stuck. I am compiling this using an ubuntu virtual machine.
Here is the code:
SYS_READ equ 3
SYS_WRITE equ 4
SYS_OPEN equ 5
SYS_CLOSE equ 6
SYS_CREATE equ 8
SYS_EXIT equ 1
section .text
global _start
_start:
mov eax, SYS_CREATE
mov ebx, filename
mov ecx, 0777
int 0x80
mov [fd_out],ebx
mov eax,SYS_WRITE
mov edx,len
mov ecx,msg
mov ebx,[fd_out]
int 0x80
mov eax,SYS_CLOSE
mov ebx,[fd_out]
int 80h
mov eax,SYS_OPEN
mov ebx,filename
mov ecx,0
mov edx,0777
int 0x80
mov [fd_in],eax
mov eax, SYS_READ
mov ebx,[fd_in]
mov ecx,info
mov edx,26
int 0x80
mov eax,SYS_WRITE
mov ebx,1
mov ecx,info
mov edx,26
int 0x80
mov eax,SYS_EXIT
mov ebx,0
int 0x80
section .data
filename db 'test.txt'
msg db 'Hello world file'
len equ $-msg
section .bss
fd_out resb 1
fd_in resb 1
info resb 26
after executing the compiled output, I get a file named test.txtHello world file.
While SYS_WRITE accepts the length of the information in EDX, the function SYS_CREATE needs a pointer to NULL terminated string for the filename.
Your filename, defined as
filename db 'test.txt'
is not NULL terminated and that is why it concatenates with the next string:
msg db 'Hello world file'
The terminating NULL in this case is the next defined:
fd_out resb 1
In order to fix it, simply define the filename with zero terminating byte:
filename db 'test.txt', 0
I wrote this code, it reads the data from user but did not display the output. It is written in Assembly language. I am new to Assembly language. Can somebody please help me in solving this. I shall be very thankful. Thanks in advance. Here is the code:
section .data ;Data segment
userMsg db 'Please enter a number: ' ;Ask the user to enter a number
lenUserMsg equ $-userMsg ;The length of the message
dispMsg db 'You have entered: '
lenDispMsg equ $-dispMsg
section .bss ;Uninitialized data
num resb 5
section .text ;Code Segment
global _start
_start:
;User prompt
mov eax, 4
mov ebx, 1
mov ecx, userMsg
mov edx, lenUserMsg
int 80h
;Read and store the user input
mov eax, 3
mov ebx, 2
mov ecx, num
mov edx, 5 ;5 bytes (numeric, 1 for sign) of that information
int 80h
;Output the message 'The entered number is: '
mov eax, 4
mov ebx, 1
mov ecx, dispMsg
mov edx, lenDispMsg
int 80h
;Output the number entered
mov eax, 4
mov ebx, 1
mov ecx, num
mov edx, 5
int 80h
; Exit code
mov eax, 1
mov ebx, 0
int 80h
In typical environments, file descripter 0 stands for standard input, 1 for standard output, and 2 for standard error output.
Reading from standard error output makes no sense for me.
Try changing the program for reading
;Read and store the user input
mov eax, 3
mov ebx, 2
mov ecx, num
mov edx, 5 ;5 bytes (numeric, 1 for sign) of that information
int 80h
to
;Read and store the user input
mov eax, 3
mov ebx, 0
mov ecx, num
mov edx, 5 ;5 bytes (numeric, 1 for sign) of that information
int 80h
in order to have the system read some data from standard input.
section .data
out1: db 'Enter the number:'
out1l: equ $-out1
out2: db 'The number you entered was:'
out2l: equ $-out2
section .bss
input: resb 4
section .text
global _start
_start:
;for displaying the message
mov eax,4
mov ebx,1
mov ecx,out1
mov edx,out1l
int 80h
;for taking the input from the user
mov eax,3
mov ebx,0
mov ecx,input
mov edx,4
int 80h
;for displaying the message
mov eax,4
mov ebx,1
mov ecx,out2
mov edx,out2l
int 80h
;for displaying the input
mov eax,4
mov ebx,1
mov ecx,input
mov edx,4
int 80h
mov eax,1
mov ebx,100
int 80h
Need to print separate token in a string in different line, but can't figure out to print out a new line.
From the tutorial I have, it says "nwln" in the examples, but it doesn't work in my code.
The code I have now only prints all the words in one line no spaces.
lab2:
cmp [ecx],byte ' '
je lab1
cmp [ecx], byte 0
je lab3
inc edx
inc ecx
jmp lab2
lab1:
sub ecx,edx
mov eax, SYS_WRITE
mov ebx, STDOUT
int 80h
add ecx, edx
inc ecx
mov edx,0
jmp lab2
ok I think I have solved it by using another variable newline in .data and another register to print a new line
Since you appear to be using NASM on Linux. nwln is a macro that is part of an Assembler Tutorial based on the code from the book Guide to Assembly Language Programming in Linux. The library is made up of a macro called nwln that prints the LineFeed(LF) character 0x0a to standard output. You can download the files io.mac and io.o from the link above. They are contained inside the ZIP file for NASM/Linux. You copy io.mac and io.o to your project directory. You have to include the macro file at the top of your program. Your code would look something like:
%include "io.mac"
SYS_EXIT equ 1
SYS_READ equ 3
SYS_WRITE equ 4
STDIN equ 0
STDOUT equ 1
section .text
global main
main:
mov ecx,msg3
mov edx,0 ; Set the length
jmp lab2
lab2:
cmp [ecx],byte ' '
je lab1
cmp [ecx], byte 0
je lab3
inc edx
inc ecx
jmp lab2
lab1:
sub ecx,edx
mov eax, SYS_WRITE
mov ebx, STDOUT
int 80h
nwln
add ecx, edx
inc ecx
mov edx,0
jmp lab2
lab3:
sub ecx,edx
mov eax, SYS_WRITE
mov ebx, STDOUT
int 80h
nwln
mov eax, SYS_EXIT
int 80h
segment .data
msg3 db 'this string', 0x0
To compile and link in a 32-bit environment you'd use something like:
nasm -f elf32 project.asm
ld -emain -melf_i386 -o project project.o io.o
You need to add io.o as a linker object to resolve the functions that are needed by the macros.
If you don't wish to rely on io.o the code below contains the equivalent macro and function that will implement nwln a similar way:
%macro nwln 0
call proc_nwln
%endmacro
SYS_EXIT equ 1
SYS_READ equ 3
SYS_WRITE equ 4
STDIN equ 0
STDOUT equ 1
section .text
global main
main:
mov ecx,msg3
mov edx,0 ; Set the length
jmp lab2
lab2:
cmp [ecx],byte ' '
je lab1
cmp [ecx], byte 0
je lab3
inc edx
inc ecx
jmp lab2
lab1:
sub ecx,edx
mov eax, SYS_WRITE
mov ebx, STDOUT
int 80h
nwln
add ecx, edx
inc ecx
mov edx,0
jmp lab2
lab3:
sub ecx,edx
mov eax, SYS_WRITE
mov ebx, STDOUT
int 80h
nwln
mov eax, SYS_EXIT
int 80h
proc_nwln:
pusha
mov eax, SYS_WRITE
mov ebx, STDOUT
mov ecx, new_line
mov edx, 0x1
int 0x80
popa
ret
segment .data
msg3 db 'this string', 0x0
new_line db 0x0a
You can then compile with something like:
nasm -f elf32 project.asm
ld -emain -melf_i386 -o project project.o