This question already has answers here:
What are file descriptors, explained in simple terms?
(13 answers)
Closed 4 years ago.
SEGMENT .data ; nothing here
SEGMENT .text ; sauce
global _start
_start:
pop ECX ; get ARGC value
mov EAX, 4 ; sys_write()
mov EBX, 1 ; /dev/stdout
;^^^^^^^^^^^
mov EDX, 1 ; a single byte
int 0x80
mov EAX, 1 ; sys_exit()
mov EBX, 0 ; return 0
int 0x80
SEGMENT .bss ; nothing here
why mov EBX, ""1"" ; /dev/stdout ?
where document I can find "1" ?
On unix systems, a process normally have 3 common I/O channels connected to it, called stdin/stdout/stderr. These have the corresponding file descriptor values 0, 1 and 2.
This is documented at: http://pubs.opengroup.org/onlinepubs/9699919799/functions/stdin.html (See also the wikipedia page )
Related
This question already has answers here:
Hello, world in assembly language with Linux system calls?
(1 answer)
What happens if there is no exit system call in an assembly program?
(1 answer)
Closed 11 months ago.
This works but I don't know what the last section does. If I remove it the code segfaults, so I'm assuming it is somehow related to closing the file or handling memory allocation but as far as I am aware that what the 6 instruction is for.
section .data
msg db 'Hello, world!', 0xa
len equ $ - msg
outfile db 'test_file.txt', 0
section .text
global _start
_start:
; creating and opening
mov eax, 8 ; set instruction
mov ebx, outfile ; set file name
mov ecx, 544o ; set file permissions
int 0x80 ; make system call
; writing to file
mov ebx, eax ; move file descriptor from previous call
mov eax, 4 ; set instruction
mov ecx, msg ; set text
mov edx, len ; set number of bytes to read
int 0x80 ; make system call
; closing file
mov eax, 6 ; set instruction
int 0x80 ; make system call
; closing program?
mov eax,1
mov ebx,0
int 0x80
This question already has answers here:
Read and print user input with x86 assembly (GNU/Linux)
(2 answers)
X86 read from stdin and write to stdout without referring the standard library
(1 answer)
Linux NASM detect EOF
(1 answer)
Closed 2 years ago.
section .bss ; you can change
user_input: resb 256 ;256 byte of memory is reserved and can be accessed through the name user_input
user_input_size equ $- user_input
section .data ;you cant change
output: db "Enter your print statement: "
output_size equ $- output
section .text ;assembly code
global _start
_start:
mov eax, 4
mov ebx, 1
mov ecx, output
mov edx, output_size
int 80
mov eax, 3
mov ebx, 0
mov ecx, user_input
mov edx, user_input_size
int 80
push ecx ; not sure about this
push edx ; not sure about this
mov eax, 4
mov ebx, 0
pop ecx
pop edx
int 80
mov eax, 1
mov ebx, 0
int 80
i want to print out "Enter your print statement: ", have the user input a statement and have that inputted statement returned to the screen. The first part is working. The others not so much. When the user enters a statement is it stored eax or ecx(user_input).
This question already has answers here:
X86 NASM Assembly converting lower to upper and upper to lowercase characters
(5 answers)
X86 Assembly Converting lower-case to uppercase
(1 answer)
Closed 3 years ago.
I want to change the string to all caps, although I am having trouble getting the length of the input. What i have tried so far is moving the address of the message into a registrar then indexing through the string and also increment a counter variable. Then comparing the char in the address to a '.' (signifying the end of the message) and if its found not to be equal it will recall this block of statements. At least this is what I want my code to do. Not sure if this is even the right logic. I know there are alot of errors and its messy but I'm learning so please just focus on my main question. thank you! EDIT: the input i use is 'this is a TEST.'
;nasm 2.11.08
SYS_Write equ 4
SYS_Read equ 3
STDIN equ 0
STDOUT equ 1
section .bss
message resb 15
counter resb 2
section .data
msg1: db 'Enter input (with a period) that I will turn into all capitals!',0xa ;msg for input
len1 equ $- msg1
section .text
global _start
_start:
mov eax, SYS_Write ; The system call for write (sys_write)
mov ebx, STDOUT ; File descriptor 1 - standard output
mov ecx, msg1 ; msg to print
mov edx, len1 ; len of message
int 0x80 ; Call the kernel
mov eax, SYS_Read ;system call to read input
mov ebx, STDIN ;file descriptor
mov ecx, message ;variable for input
mov edx, 15 ;size of message
int 0x80 ;kernel call
mov [counter], byte '0'
getLen:
mov eax, message
add eax, [counter]
inc byte [counter]
cmp eax, '.'
jne getLen
mov eax, SYS_Write ; this is to print the counter to make sure it got the right len
mov ebx, STDOUT
mov ecx, counter
mov edx, 2
int 0x80
jmp end
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
mov eax, [message]
;add eax, counter
cmp eax, 90
jg toUpper
toUpper:
sub eax, 32
mov [message], eax
mov eax, SYS_Write ; The system call for write (sys_write)
mov ebx, STDOUT ; File descriptor 1 - standard output
mov ecx, message ; Put the offset of hello in ecx
mov edx, 10 ; helloLen is a constant, so we don't need to say
int 0x80 ; Call the kernel
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
end:
mov eax,1 ; The system call for exit (sys_exit)
mov ebx,0 ; Exit with return code of 0 (no error)
int 0x80 ;
This question already has answers here:
How to convert a binary integer number to a hex string?
(3 answers)
Closed 3 years ago.
I am trying to print address of variable in NASM x86 assembly. When I assemble this code it assembles fine, however when I run this code it prints two characters instead of the address.
section .bss
Address: RESB 4
section .data
variable db 1
section .text
global _start
_start:
mov eax , variable ; variable Address is stored in eax register
mov [Address] , dword eax ; move the value of eax to Address
mov eax , 4 ; write system call in linux
mov ebx , 1 ; stdout file descriptor
mov ecx , Address ; memory address to be printed.
mov edx , 4 ; 4 bytes to be print
int 0x80
mov eax , 1
int 0x80
screenshot:
You should just format the output as hex number. You can use printf from C for this purpose
extern printf
section .bss
Address: RESB 4
section .data
variable db 1
fmt db "0x%x", 10, 0 ; format string
section .text
global _start
_start:
mov eax , variable ; variable Address is stored in eax register
mov [Address] , dword eax ; move the value of eax to Address
push dword [Address] ; push value of Address
push dword fmt ; address of format string
call printf ; calling printf
add esp, 8 ; pop stack 2*4 bytes after passing two variables to printf
mov eax, 0 ; exit code 0
int 0x80
Any good NASM/Intel Assembly programmers out there? If so, I have a question for you!
Every tutorial I can find online, shows the usage of "printf" for printing the actual value of ARGC to the screen (fd:/dev/stdout). Is it not possible to simply print it with sys_write() for example:
SEGMENT .data ; nothing here
SEGMENT .text ; sauce
global _start
_start:
pop ECX ; get ARGC value
mov EAX, 4 ; sys_write()
mov EBX, 1 ; /dev/stdout
mov EDX, 1 ; a single byte
int 0x80
mov EAX, 1 ; sys_exit()
mov EBX, 0 ; return 0
int 0x80
SEGMENT .bss ; nothing here
When I run this, I get no output at all. I have tried copying ESP into EBP and tried using byte[EBP+4], (i was told the brackets de-reference the memory address).
I can confirm that the value when compared to a constant, works. For instance,
this code works:
pop ebp ; put the first argument on the stack
mov ebp, esp ; make a copy
cmp byte[ebp+4],0x5 ; does it equal 5?
je _good ; goto _good, &good, good()
jne _bad ; goto _bad, &bad, bad()
When we "pop" the stack, we technically should get the full number of arguments, no? Oh, btw, I compile with:
nasm -f elf test.asm -o test.o
ld -o test test.o
not sure if that is relevant. Let me know if i need to provide more information, or format my code for readability.
At least 2 problems.
You need to pass a pointer to the thing you want to print.
You probably want to convert to text.
Something like this should work:
SEGMENT .text ; sauce
global _start
_start:
mov ecx, esp ; pointer to ARGC on stack
add byte [esp], '0' ; convert to text assuming single digit
mov EAX, 4 ; sys_write()
mov EBX, 1 ; /dev/stdout
mov EDX, 1 ; a single byte
int 0x80
mov EAX, 1 ; sys_exit()
mov EBX, 0 ; return 0
int 0x80
Everyone's comments where very helpful! I am honored that you all pitched in and helped! I have used #Jester's code,
SEGMENT .text ; sauce
global _start
_start:
mov ecx, esp ; pointer to ARGC on stack
add byte [esp], '0' ; convert to text assuming single digit
mov EAX, 4 ; sys_write()
mov EBX, 1 ; /dev/stdout
mov EDX, 1 ; a single byte
int 0x80
mov EAX, 1 ; sys_exit()
mov EBX, 0 ; return 0
int 0x80
Which works perfectly when compiled, linked and loaded. The sys_write() function requires a pointer, such like in the common "Hello World" example, the symbol "msg" is a pointer as seen in the code below.
SECTION .data ; initialized data
msg: db "Hello World!",0xa
SECTION .text ; workflow
global _start
_start:
mov EAX, 4
mov EBX, 1
mov ECX, msg ; a pointer!
So first, we move the stack pointer into the counter register, ECX, with the code,
mov ecx, esp ; ecx now contains a pointer!
and then convert it to a string by adding a '0' char to the value pointed to by ESP (which is ARGC), by de-referencing it with square brackets, as [ESP] like so,
add byte[esp], '0' ; update the value stored at "esp"
Again, thank you all for the great help! <3