How to display data and address in nasm 64-bit? - nasm

I am doing a practical assignment. And I have made an array and I want to display data and address simultaneously in the format (address: data). How to do that? What changes do I need to do in my code? How to use rsi again for displaying address?
The link to my code is:
http://rextester.com/AQMJ86771

Normally it is not good practice to do assignments for someone, but because you're so close, I'll endulge
%macro disp 2
push rsi
push rcx
mov rax,1
mov rdi,1
mov rsi,%1
mov rdx,%2
syscall
pop rcx
pop rsi
%endmacro
section .data
msg1 db "Menu : ",10
db "1.NOWOS",10
db "2.NOWS ",10
db "3.OWOS ",10
db "4.OWS ",10
l1 equ $-msg1
newline db 0AH
colon db ' : '
src dq 01H,02H,03H,04h,05h
dst dq 00h,00h,00h,00h,00h
section .bss
buff resb 16
pcount resb 1
ncount resb 1
section .code
global _start
_start:
disp msg1,l1
mov rsi,src
mov rcx,5
back:
mov rax, rsi
call disp16num
disp colon, 3
lodsq
call disp16num
disp newline,1
loop back
mov rax,60
mov rdi,0
syscall
disp16num:
push rcx
push rsi
mov rsi, buff
mov rcx, 16
mov rbx, rax
back1:
rol rbx,4
mov al,bl
and al,0FH
cmp al,09H
jbe add30
add al,7H
add30:
add al,30H
mov [rsi],al
inc rsi
loop back1
disp buff,16
pop rsi
pop rcx
ret
Which will give you this output.
Menu :
1.NOWOS
2.NOWS
3.OWOS
4.OWS
00000000006001B4 : 0000000000000001
00000000006001BC : 0000000000000002
00000000006001C4 : 0000000000000003
00000000006001CC : 0000000000000004
00000000006001D4 : 0000000000000005

Related

Printing binary string in assembly

I'm writing a program to print binary string of a hardcoded word. Here is how it looks like currently:
main.asm
section .text
global _start
extern _print_binary_content
_start:
push word [word_to_print] ; pushing word. Can we push just one byte?
call _print_binary_content
mov rax, 60
mov rdi, 0
syscall
section .data
word_to_print: dw 0xAB0F
printer.asm
SYS_BRK_NUM equ 0x0C
BITS_IN_WORD equ 0x10
SYS_WRITE_NUM equ 0x01
STD_OUT_FD equ 0x01
FIRST_BIT_BIT_MASK equ 0x01
ASCII_NUMBER_OFFSET equ 0x30
section .text
global _print_binary_content
_print_binary_content:
pop rbp
xor ecx, ecx ;zeroing rcx
xor ebx, ebx ;zeroing rbx
pop bx ;the word to print the binary content of
;sys_brk for current location
mov rax, SYS_BRK_NUM
mov rdi, 0
syscall
;end sys_brk
mov r12, rax ;save the current brake location
;sys_brk for memory allocation 16 bytes
lea rdi, [rax + BITS_IN_WORD]
mov rax, SYS_BRK_NUM
syscall
;end sys_brk
xor ecx, ecx
mov cl, byte BITS_IN_WORD - 1; used as a counter in the loop below
loop:
mov dx, bx
and dx, FIRST_BIT_BIT_MASK
add dx, ASCII_NUMBER_OFFSET
mov [r12 + rcx], dl
shr bx, 0x01
dec cl
cmp cl, 0
jge loop
mov rsi, r12
mov rax, SYS_WRITE_NUM
mov rdi, STD_OUT_FD
mov rdx, BITS_IN_WORD
syscall
push rbp ; pushing return address back
ret
If I compile link and run this program it works. But the question is about performance and maybe conventions of writing assembly programs. In the file printer.asm I cleaned ecx twice which looks kind of not optimal. Maybe some registers were used not by their purpose (I used intel-manual).
Can you please help me to improve this very simple program?

NASM: SegFault on MOV ECX

I'm trying to make a very simple assembly program run, however I seem to get segfaults whatever I do.
Here is my code (should print 'a' on a linux machine)
section .data
buffer times 50 db 97
pointer db 0
section .text
global _start
_start:
mov ECX , pointer
mov EDX , [buffer + ECX]
mov EAX , 4
mov EBX , 1
mov ECX , EDX
mov EDX , 1
int 0x80
It causes a segfault on the first MOV but it seems obvious to me that it should work.
I reduced it to almost nothing and it still segfault.
section .data
msg db "hello"
section .text
global _start
_start:
mov EAX,1
I've run this succesfully:
section .text
global _start
_start:
mov ax, 0b
dec ax
sub ax, 11111111b
mov bx, 97
add ax, bx
mov [INVENTORY], ax ; put a in first inventory pos
mov eax, 4
mov ebx, 1
mov ecx, INVENTORY
mov edx, 1
int 0x80
mov ax, [INVENTORY]
add ax, 1
mov [INVENTORY + 1], ax ; put b in second inventory pos
mov [VAR], ax
mov eax, 4
mov ebx, 1
mov ecx, VAR
mov edx, 1
int 0x80
mov eax, 4
mov ebx, 1
mov ecx, '\n'
mov edx, 1
int 0x80
mov eax,1
int 0x80
_newline:
section .data
VAR DW 0
INVENTORY TIMES 8 DW 0
Is it possible that it has to do with the symbols I use for newlines or tabs? I generate the assembly from java and I use \t for tabs and \n for new lines (and spaces so it doesn't look too bad.
I'm using NASM and I'm running it here:
https://www.tutorialspoint.com/compile_assembly_online.php
Thank you!
If you are just trying to print out a set of 'a's.
section .data
buffer times 50 db 97
len.buffer equ $-buffer
pointer db 0
section .text
global _start
_start:
; ssize_t write(int fd, const void *buf, size_t count);
; i386 ebx ecx edx esi edi ebp
mov EAX , 4 ; write syscall
mov EBX , 1 ; std out
lea ecx, [buffer] ; buffer
mov edx, len.buffer ; size
int 0x80
_exit:
mov eax, 1 ; exit syscall
int 0x80
output:
./yvon_001
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\ndavid#ubuntuserver00A:~/asm$ ./yvon_001
In the end #MichealPetch was right, I needed to add an EXIT syscall at the end of the code. The sample I tried still did a SEGFAULT because I was moving pointer instead of [pointer] in a registry.
Thanks for comments and answers!

error of floating point exception(core dumped)

global _start
section .data
var dq 12494F04A6344129h
msg db "The number of times 4 present in the given number"
len equ $-msg
novar db 00
section .bss
section .text
mov dl,0Ah
mov cl,10
_start :
mov rsi,var
up: mov al,byte ptr [rsi]
mov ah,00
div dl
cmp ah,04
je dn
jne dn1
dn: inc byte[novar]
dn1: inc rsi
dec cl
jne up
jmp exit
exit: mov eax,4
mov ebx,1
mov ecx,msg
mov edx,len
int 80h
mov eax,4
mov ebx,1
mov ecx,novar
mov edx,1
int 80h
mov eax,1
mov ebx,0
int 80h
Nasm doesn't use "ptr" - that won't even assemble.
The first two lines - above the _start: label - are never executed, so those registers are never initialized. That's probably what causes the exception. dl is probably zero!
len is fine - it's an equate, not a variable.
You probably want to add the character '0' to novar before printing it.
None of this looks useful to me. Are you sure this is the question you're trying to answer, #Shubham Satpute?

mov edx overwrites cx register

I'm trying to print Hi 10 times. This is my code.
section .data
msg db "Hi"
section .text
global _start
_start:
mov cx, 10
L1:
mov eax, 4
mov ebx, 1
mov ecx, msg
mov edx, 3
int 0x80
dec cx
jnz L1
mov eax, 1
mov ebx, 0
int 0x80
gdb reports that mov edx, 3 overwrites the cx register to some crazy value and so the loop keeps going forever.
What am i doing wrong? Is it because they are the same register?
How does one program in assembly with so few registers?
Compiling on centos with nasm and ld
Thanks
You're looking at the wrong line. The problem is "mov ecx, msg". ECX is the extended register of which CX is the lower part, so you're writing over it.
It's best to save your loop counter on the stack, because who knows that the 'int' call might change. Add 'push cx' (or ecx) after 'L1:'. and 'pop cx' after the 'int' call to preserve the contents of the register.
This code fixes it:
section .data
msg db "Hi"
counter dw 10
section .text
global _start
_start:
L1:
mov eax, 4
mov ebx, 1
mov ecx, msg
mov edx, 2
int 0x80
mov cx, [counter]
dec cx
mov [counter], cx
jnz L1
mov eax, 1
mov ebx, 0
int 0x80
move the value into a variable and then dec it then put it back

64bit NASM file handling problems

I managed to write a NASM program on my 64bit Linux system which removes non-letter symbols from an input and prints each word in separate line. The problem is that I get RCX = -1 where i have to get the readed character number , and as a result I get segmentation fault. I've already spent hours trying to figure out how to fix this bug. Hope you guys will be able to help me. Thanks in advance.
Heres my code:
section .data
file1 db "data", 0
file2 db "results", 0
text times 255 db 0
textSize equ $ - text
buff times 255 db 0
buffSize equ $ - buff
section .text
global main
main:
mov rax, 2
mov rdi, file1
mov rsi, 0 ;read only
mov rdx, 0x7777
syscall ;open file1
mov rbx, rax ;save fd to rbx
mov rsi, text ; a pointer to the current character
mov rax, 0
mov rdi, rbx ;fd of file1
mov rsi, text
mov rdx, textSize
syscall ;read the text from file1
mov rax, 3
mov rdi, rbx
syscall ;close file1
mov rcx, rax ; rcx - character counter
mov rbx, buff ;rbx will be our buffer
cmp rcx, 0
je exit ; if nothing to read - exit
process_loop1:
mov dl, byte[rsi]
cmp byte[rsi], 0x41 ; "A"
jl inc1
cmp byte[rsi], 0x5a ; "Z"
jle save
cmp byte[rsi], 0x61 ; "a"
jl inc1
cmp byte[rsi], 0x7a ; "z"
jle save
jmp inc1 ;check text
inc1:
inc rsi
dec rcx
jnz process_loop1
jmp print
save:
mov byte [ebx], dl
jmp inc2 ;save letters
inc2:
inc rsi
inc rbx
dec rcx
jnz process_loop2
jmp print
process_loop2:
mov dl, byte[rsi]
cmp byte[rsi], 0x41 ; "A"
jl enter
cmp byte[rsi], 0x5a ; "Z"
jle save
cmp byte[rsi], 0x61 ; "a"
jl enter
cmp byte[rsi], 0x7a ; "z"
jle save
jmp enter
enter:
mov byte [ebx], 10 ;enter
inc rsi
inc rbx
dec rcx
jnz process_loop1
jmp print
print:
mov rax, 2
mov rdi, file2
mov rsi, 1 ;write only
mov rdx, 0x7777
syscall ;open file2
mov rbx, rax ;save fd to rbx
mov rax, 1
mov rdi, rbx
mov rsi, buff
mov rdx, buffSize
syscall ;print result
mov rax, 3
mov rdi, rbx
syscall ;close file2
jmp exit
exit:
mov rax, 60
mov rdi, 0
syscall
You have a sys_close between the sys_read and the time you try to check the number of bytes received. Thus, you are checking the return value of the close, not the read. Also note that rcx is destroyed by syscall so you can't just move up the mov rcx, rax line.
Also, in a few places you use [ebx] instead of [rbx].
Furthermore, you probably want use O_CREAT for the result file and only write as many bytes as you have processed, not buffSize.
section .data
filename db 'AVG.asm'
section .bss
buffer resb 2000
fd_in resb 1
section .text
global _start
_start:
mov rax,2
mov rdi,filename
mov rsi,0
mov rdx,0777
syscall
mov [fd_in],rax
mov rax,0
mov rdi,[fd_in]
mov rsi,buffer
mov rdx,2000
syscall
mov rax,1
mov rdi,1
mov rsi,buffer
mov rdx,2000
syscall
mov rax,3
mov rdi,[fd_in]
syscall
mov rax,60
mov rdi,0
syscall

Resources