Accessing struc members NASM Assembly - nasm

Coming from Object Oriented languages such as Python and Java, why is this code not working as I would like it to?
I want to access the cat struc variable cat_name and send it to STDOUT to print in my terminal.
catstruct.asm:
SECTION .bss
struc cat
cat_name: resb 8
endstruc
SECTION .data
catStruc:
istruc cat
at cat_name, db "Garfield"
iend
SECTION .text
GLOBAL _start
_start:
mov edx, 8
mov ecx, cat_name
mov ebx, 1
mov eax, 4
int 0x80
mov ebx, 0
mov eax, 1
int 0x80
No errors when the code assembles, however, it does not print anything when I run it. How come?

cat_name just contains 0, the offset of the cat name from the start of the struct, you need
mov ecx, catStruct+cat_name
quote from the manual
For example, to define a structure called mytype containing a
longword, a word, a byte and a string of bytes, you might code
struc mytype
mt_long: resd 1
mt_word: resw 1
mt_byte: resb 1
mt_str: resb 32
endstruc
The above code defines six symbols: mt_long as 0 (the offset from the
beginning of a mytype structure to the longword field), mt_word as 4,
mt_byte as 6, mt_str as 7, mytype_size as 39, and mytype itself as
zero.

Related

NASM one wrong way checking data

So, I write a program that creates matrix 4x5 and I have almost done it. I store data in the strings in order to check what information is stored there. When I enter data properly - Ok, but if I make even just one mistake (for example +12asd) then I see my program works again from the "array[3][0]" when I have entered it. What is wrong?
; Task: write a program that allows to enter 2-D array 4x5. Show only 2 first columns.
section .bss ; The section intended for uninitilizated data
string_00 resb 7
string_01 resb 7
string_02 resb 7
string_03 resb 7
string_04 resb 7
string_10 resb 7
string_11 resb 7
string_12 resb 7
string_13 resb 7
string_14 resb 7
string_20 resb 7
string_21 resb 7
string_22 resb 7
string_23 resb 7
string_24 resb 7
string_30 resb 7
string_31 resb 7
string_32 resb 7
string_33 resb 7
string_34 resb 7
section .data ; The section designed for using initilizated data
pointer_0 dd string_00, string_01, string_02, string_03, string_04
pointer_1 dd string_10, string_11, string_12, string_13, string_14
pointer_2 dd string_20, string_21, string_22, string_23, string_24
pointer_3 dd string_30, string_31, string_32, string_33, string_34
pointer dd pointer_0, pointer_1, pointer_2, pointer_3
external_counter dd 0
internal_counter dd 0
section .text
global _start
_start:
call _check
ex:
mov ebx, 0
mov eax, 1
int 0x80
_print:
mov ebx, 1
mov eax, 4
int 0x80
ret
_enter:
mov edx, 7
mov ebx, 0
mov eax, 3
int 0x80
ret
_make_esi:
mov eax, [pointer]
mov ebx, [external_counter]
mov esi, [eax + ebx * 4]
mov ebx, [internal_counter]
add ebx, ebx
add ebx, ebx
add ebx, ebx
add esi, ebx
ret
_check:
call _make_esi
cmp esi, string_01
je ex
mov ecx, esi
call _enter
inc dword [internal_counter]
jmp _check

Assembly on Linux: unexpected behaviour from Assembly [duplicate]

This question already has answers here:
In NASM labels next to each other in memory are printing both strings instead of first one
(1 answer)
How does $ work in NASM, exactly?
(2 answers)
Closed 4 years ago.
running the code below generates a file with Welcome to jj Shashwat as content. what i didn't get is why does it writes Shashwat at the end of the file, Shashwat is in a totally different variable. Any idea why does this happen?
section .text
global _start ;must be declared for using gcc
_start:
;create the file
mov eax, 8
mov ebx, file_name
mov ecx, 0777 ;read, write and execute by all
int 0x80 ;call kernel
mov [fd_out], eax
; close the file
mov eax, 6
mov ebx, [fd_out]
;open the file for reading
mov eax, 5
mov ebx, file_name
mov ecx, 2 ;for read/write access
mov edx, 0777 ;read, write and execute by all
int 0x80
mov [fd_out], eax
; write into the file
mov edx,len ;number of bytes
mov ecx, msg ;message to write
mov ebx, [fd_out] ;file descriptor
mov eax,4 ;system call number (sys_write)
int 0x80 ;call kernel
; close the file
mov eax, 6
mov ebx, [fd_out]
mov eax,1 ;system call number (sys_exit)
int 0x80 ;call kernel
section .data
file_name db 'myfile.txt', 0
msg db 'Welcome to jj', 0
mgafter db ' Shashwat', 0
lntwo equ $-mgafter
len equ $-msg
section .bss
fd_out resb 1
fd_in resb 1
info resb 26
That's because you said len equ $-msg after defining both msg and msgafter, so len is set to the length of both msg and msgafter, making your write call write both strings. This is because len equ $-msg means “set len to be the difference between the current location ($) and the location of msg.”
To fix this, move the len equ $-msg line right after the definition of msg.

How do I start printing from the middle of a string in ASM?

I have an assignment that requires me to print out characters starting from a certain position in a string (ranging anywhere within the string) and I cannot seem to figure out how to do it. This is the code that I have tried so far
SYS_EXIT equ 1
SYS_READ equ 3
SYS_WRITE equ 4
STDIN equ 0
STDOUT equ 1
segment .bss
curLen resb 1
section .text
global main
main:
mov ecx,2
mov [curLen],ecx ; Store starting position
mov edx,10 ; Only print out 10 characters
mov ecx,txt ; Load string address into register
add ecx,curLen ; Add starting position to string address
mov ebx,STDOUT ;
mov eax,SYS_WRITE
int 0x80
jmp exit
exit:
mov eax,SYS_EXIT
int 0x80
section .data
txt db 'This a string', 0x0
Any idea what could be going wrong? Ideally the above code would print out "is is a st", which starts two characters into the string and prints out the following 10.
Thanks!

Correct User Input - x86 Linux Assembly

So I am working on an x86 Assembly program for Linux using NASM. This program basically asks the user for their name and their favorite color. After doing this and storing the two strings in variables declared in the .bss section, the program prints "No way name of user, favorite color is my favorite color, too!
The problem I am having is that there are enormous spaces in the output because I do not know how long the string was that the user entered, only the length that I declared the buffer to be.
section .data
greet: db 'Hello!', 0Ah, 'What is your name?', 0Ah ;simple greeting
greetL: equ $-greet ;greet length
colorQ: db 'What is your favorite color?' ;color question
colorL: equ $-colorQ ;colorQ length
suprise1: db 'No way '
suprise1L equ $-suprise1
suprise3: db ' is my favorite color, too!', 0Ah
section .bss
name: resb 20 ;user's name
color: resb 15 ;user's color
section .text
global _start
_start:
greeting:
mov eax, 4
mov ebx, 1
mov ecx, greet
mov edx, greetL
int 80 ;print greet
getname:
mov eax, 3
mov ebx, 0
mov ecx, name
mov edx, 20
int 80 ;get name
askcolor:
;asks the user's favorite color using colorQ
getcolor:
mov eax, 3
mov ebx, 0
mov ecx, name
mov edx, 20
int 80
thesuprise:
mov eax, 4
mov ebx, 1
mov ecx, suprise1
mov edx, suprise1L
int 80
mov eax, 4
mov ebx, 1
mov ecx, name
mov edx, 20
int 80
;write the color
;write the "suprise" 3
mov eax, 1
mov ebx, 0
int 80
The code for what I am doing is above. Does anyone have a good method for finding the length of the entered string, or of taking in a character at a time to find out the length of the string?
Thank you in advance.
After int80 in getname returns, EAX will contain the number of bytes actually read, or a negative error indication.
You should
check for error return
store the return value, as it gives you the length of input
Equivalent code in C:
char name[20];
int rc;
rc = syscall(SYS_read, 0, name, 20-1); // leave space for terminating NUL
if (rc < 0) {
// handle error
} else {
name[rc] = '\0'; // NUL terminate the string
}

NASM Code In Linux Gives Me Segmentation Fault

I started learning how to write programs using the NASM assembly programming language. I wrote this simple program that prompts the user to enter two numbers and then adds the two operands together. I got it to compile with no errors or warnings, but when it prompts the user for the two numbers and it begins to add the two numbers it prints out segmentation fault and program ends. I know a segmentation fault is the equivalent to an access reading / writing violation exception in the Win32 world. But, because I don't know how to debug NASM code; I can't figure out what is wrong. I suspect it has to do with an invalid pointer; but I don't know. Here is the code below:
section .data
msg1: db 'Please Enter A Number: ', 0
length1: equ $ - msg1
msg2: db 'Please Enter A Second Number: ', 0
length2: equ $ - msg2
section .bss
operand1: resb 255
operand2: resb 255
answer: resb 255
section .text
global _start
_start:
; Print first message
mov eax, 4
mov ebx, 1
mov ecx, msg1
mov edx, length1
int 80h
; Now read value
mov eax, 3
mov ebx, 1
mov ecx, operand1
mov edx, 255
int 80h
; Print second message
mov eax, 4
mov ebx, 1
mov ecx, msg2
mov edx, length2
int 80h
; Now read second value
mov eax, 3
mov ebx, 1
mov ecx, operand2
mov edx, 255
int 80h
; Now add operand1 and operand2 and print answer
mov eax, 4
mov ebx, 1
xor ecx, ecx ; Make the ecx register 0
mov ecx, operand1
add ecx, operand2
mov edx, 510
int 80h
(Aside: you should be reading from STDIN_FILENO = 0, not STDOUT_FILENO = 1. Also, you're writing a NUL character and you shouldn't.)
The problem is that operand1 and operand2 are addresses to memory locations holding characters you've read. When you add them, you get a pointer to invalid memory.
You'll have to convert them to integers, add them, and convert back to a string, before you can write it out.
Value in ecx is an address of string that is to be printed when you call int 80h. Last part does not make sense
mov eax, 4
mov ebx, 1
xor ecx, ecx ; Make the ecx register 0
mov ecx, operand1
add ecx, operand2 ; **<<< invalid memory address now in ECX !!!**
mov edx, 510
int 80h
because you are adding address of string operand1 and address of string operand2 and trying to print whatever is located ant resulting address which is most likely points to nowhere.
To debug your program with gdb you can do:
nasm -f elf64 -g -l q1.lst q1.asm
gcc -o q1 q1.o
I replaced the "_start" with "main" so that gcc won't complain, and you can skip the 64 in "-f elf64" if you are building on 32 bit platform.
gdb q1
Here is an example f gdb session:
(gdb) br main
Breakpoint 1 at 0x4004d0: file q1.asm, line 20.
(gdb) r
Starting program: /home/anonymous/Projects/asm/q1
Breakpoint 1, main () at q1.asm:20
20 mov eax, 4
(gdb) n
21 mov ebx, 1
(gdb) n
22 mov ecx, msg1
(gdb) n
23 mov edx, length1
(gdb) p msg1
$1 = 1634036816
(gdb)

Resources