When compiled and ran this piece of assembly code throws a Segmentation fault which I can't figure out
section .data
section .bss ; Uninitialized data
x resb 5
section .text
global _start ; entry point for linker (ld)
_start:
; Grab input from user
mov eax, 3 ; system call number (sys_read)
mov ebx, 2
mov ecx, x
mov edx, 5 ; 5 bytes 1 for the sign 4 for the numbers
;Output the number entered
mov eax, 4 ; system call number (sys_write)
mov ebx, 1
mov ecx, x
mov edx, 5
int 0x80 ; kernel call
The goal is to declare a number inside the code and then output the value to the screen
looks like I forgot to do the kernel calls that is why it results in a segfault
section .data
section .bss ; Uninitialized data
x resb 5
section .text
global _start ; entry point for linker (ld)
_start:
; Grab input from user
mov eax, 3 ; system call number (sys_read)
mov ebx, 2
mov ecx, x
mov edx, 5 ; 5 bytes 1 for the sign 4 for the numbers
int 0x80 ; kernel call
;Output the number entered
mov eax, 4 ; system call number (sys_write)
mov ebx, 1
mov ecx, x
mov edx, 5
int 0x80 ; kernel call
; return 0
mov eax, 1
mov ebx, 0
int 80h ; kernel call
Related
I'm a novice Assembly x86 Learner, and i want to add two numbers (5+5) and print the result on the screen.
here is my code:
global _start
section .text
_start:
mov eax, 5
mov ebx, 5
add eax, ebx
push eax
mov eax, 4 ; call the write syscall
mov ebx, 1 ; STDOUT
pop ecx ; Result
mov edx, 0x1
int 0x80
; Exit
mov eax, 0x1
xor ebx, ebx
int 0x80
Correct me please
Another approach to convert an unsigned integer to a string and write it:
section .text
global _start
_start:
mov eax, 1234567890
mov ebx, 5
add eax, ebx
; Convert EAX to ASCII and store it onto the stack
sub esp, 16 ; reserve space on the stack
mov ecx, 10
mov ebx, 16
.L1:
xor edx, edx ; Don't forget it!
div ecx ; Extract the last decimal digit
or dl, 0x30 ; Convert remainder to ASCII
sub ebx, 1
mov [esp+ebx], dl ; Store remainder on the stack (reverse order)
test eax, eax ; Until there is nothing left to divide
jnz .L1
mov eax, 4 ; SYS_WRITE
lea ecx, [esp+ebx] ; Pointer to the first ASCII digit
mov edx, 16
sub edx, ebx ; Count of digits
mov ebx, 1 ; STDOUT
int 0x80 ; Call 32-bit Linux
add esp, 16 ; Restore the stack
mov eax, 1 ; SYS_EXIT
xor ebx, ebx ; Return value
int 0x80 ; Call 32-bit Linux
This question already has answers here:
How do I print an integer in Assembly Level Programming without printf from the c library? (itoa, integer to decimal ASCII string)
(5 answers)
How exactly does binary code get converted into letters?
(6 answers)
Closed 4 years ago.
The given below program adds two numbers 3 and 4 in nasm.Why in this code the eax which contain 3 and ebx which contain 4 are subtracted by 0 ,and result of sum which is stored in eax is added with zero?,code is given below ,while i tried without these add ,and sub by zero lines it shows unexpected result.
section .text
global _start ;must be declared for using gcc
_start: ;tell linker entry point
mov eax, '3'
sub eax, '0'
mov ebx, '4'
sub ebx, '0'
add eax, ebx
add eax, '0'
mov [sum], eax
mov ecx, msg
mov edx, len
mov ebx, 1 ;file descriptor (stdout)
mov eax, 4 ;system call number (sys_write)
int 0x80 ;call kernel
mov ecx, sum
mov edx, 1
mov ebx, 1 ;file descriptor (stdout)
mov eax, 4 ;system call number (sys_write)
int 0x80 ;call kernel
mov eax, 1 ;system call number (sys_exit)
int 0x80 ;call kernel
section .data
msg db "The sum is:", 0xA,0xD
len equ $ - msg
segment .bss
sum resb 1
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 try write follow code, use int 0x80 to print number 5 but it don't print anything.
segment .bss
num1 resb 1
section .text
global _start
_start:
mov dword [num1],5
add [num1],byte '0'
mov ecx, dword [num1]
mov eax, 4
mov ebx, 1
mov edx, 1
int 0x80
mov eax, 1
int 0x80
System call 4 expects ecx to contain a pointer to a NUL-terminated string.
So instead of mov ecx, dword [num1] you should use mov ecx, num1.
I am trying to print a single digit integer in nasm assembly on linux. What I currently have compiles fine, but nothing is being written to the screen. Can anyone explain to me what I am doing wrong here?
section .text
global _start
_start:
mov ecx, 1 ; stores 1 in rcx
add edx, ecx ; stores ecx in edx
add edx, 30h ; gets the ascii value in edx
mov ecx, edx ; ascii value is now in ecx
jmp write ; jumps to write
write:
mov eax, ecx ; moves ecx to eax for writing
mov eax, 4 ; sys call for write
mov ebx, 1 ; stdout
int 80h ; call kernel
mov eax,1 ; system exit
mov ebx,0 ; exit 0
int 80h ; call the kernel again
This is adding, not storing:
add edx, ecx ; stores ecx in edx
This copies ecx to eax and then overwrites it with 4:
mov eax, ecx ; moves ecx to eax for writing
mov eax, 4 ; sys call for write
EDIT:
For a 'write' system call:
eax = 4
ebx = file descriptor (1 = screen)
ecx = address of string
edx = length of string
After reviewing the other two answers this is what I finally came up with.
sys_exit equ 1
sys_write equ 4
stdout equ 1
section .bss
outputBuffer resb 4
section .text
global _start
_start:
mov ecx, 1 ; Number 1
add ecx, 0x30 ; Add 30 hex for ascii
mov [outputBuffer], ecx ; Save number in buffer
mov ecx, outputBuffer ; Store address of outputBuffer in ecx
mov eax, sys_write ; sys_write
mov ebx, stdout ; to STDOUT
mov edx, 1 ; length = one byte
int 0x80 ; Call the kernel
mov eax, sys_exit ; system exit
mov ebx, 0 ; exit 0
int 0x80 ; call the kernel again
From man 2 write
ssize_t write(int fd, const void *buf, size_t count);
In addition to the other errors that have been pointed out, write() takes a pointer to the data and a length, not an actual byte itself in a register as you are trying to provide.
So you will have to store your data from a register to memory and use that address (or if it's constant as it currently is, don't load the data into a register but load its address instead).