LinuxQuestions.org
Review your favorite Linux distribution.
Home Forums Tutorials Articles Register
Go Back   LinuxQuestions.org > Forums > Non-*NIX Forums > Programming
User Name
Password
Programming This forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game.

Notices


Reply
  Search this Thread
Old 11-08-2017, 08:24 PM   #1
tpalmerstudios
LQ Newbie
 
Registered: Feb 2016
Location: Dallas, Texas
Distribution: ElementaryOS on Lenovo Z50-70
Posts: 22
Blog Entries: 2

Rep: Reputation: 10
Question Assembly Program Function Calls


I am beginning in assembly and have created the Hello World program. My next step was to work with functions so I made this little program
Code:
section .data
        welcome db "Hello, World!",0x0a
        goodbye db "Goodbye, World!", 0x0a
        main db "What's Up",0x0a
        mainLength equ $ - main
        welcomeLength equ $ - welcome
        goodbyeLength equ $ - goodbye

section .text
global  _start

_start:
        jmp start
        mov rax,4
        mov rbx,1
        mov rcx,main
        mov rdx,mainLength
        int 0x80
        jmp end
start:
        mov rax,4
        mov rbx,1
        mov rcx,welcome
        mov rdx,welcomeLength
        int 0x80
        ret
end:
        mov rax,4
        mov rbx,1
        mov rcx,goodbye
        mov rdx,goodbyeLength
        int 0x80
        mov rax, 1
        mov rbx, 0
        int 0x80
The issue is that my expected result is
Code:
Hello, World!
Whats Up
Goodbye, World!
But instead I'm getting
Code:
Hello, World!
Goodbye, World!
Whats Up
Segmentation Fault (core dumped)
So for some reason, the functions aren't being called in the right order and I am not exiting correctly.
 
Old 11-08-2017, 11:09 PM   #2
NevemTeve
Senior Member
 
Registered: Oct 2011
Location: Budapest
Distribution: Debian/GNU/Linux, AIX
Posts: 4,862
Blog Entries: 1

Rep: Reputation: 1869Reputation: 1869Reputation: 1869Reputation: 1869Reputation: 1869Reputation: 1869Reputation: 1869Reputation: 1869Reputation: 1869Reputation: 1869Reputation: 1869
Just remove the 'jump' and 'ret' instructions.
 
Old 11-09-2017, 12:39 AM   #3
dogpatch
Member
 
Registered: Nov 2005
Location: Central America
Distribution: Mepis, Android
Posts: 490
Blog Entries: 4

Rep: Reputation: 238Reputation: 238Reputation: 238
Your string length constants ought to each follow its own string. As coded, for example, 'welcomeLength' is the length of all 3 strings.

Then, you're not really calling functions here. Just jumping to the welcome message which as noted above is all 3 strings concatenated. The 'ret' instuction then attempts to return where there was no call.

I think you want to have 3 calls in your top section of code. Initialize, then call each function (using the 'call' instruction). Keep the 'ret' instructions in each function. That will return to the main section. After the 3 calls, exit.

Last edited by dogpatch; 11-09-2017 at 12:43 AM.
 
1 members found this post helpful.
Old 11-09-2017, 01:47 AM   #4
tpalmerstudios
LQ Newbie
 
Registered: Feb 2016
Location: Dallas, Texas
Distribution: ElementaryOS on Lenovo Z50-70
Posts: 22

Original Poster
Blog Entries: 2

Rep: Reputation: 10
Thanks dogpatch. That solved my problem. The first issue with the size of the strings, why is that a problem? Does '$' refer to the variable before it?
 
Old 11-09-2017, 05:04 AM   #5
NevemTeve
Senior Member
 
Registered: Oct 2011
Location: Budapest
Distribution: Debian/GNU/Linux, AIX
Posts: 4,862
Blog Entries: 1

Rep: Reputation: 1869Reputation: 1869Reputation: 1869Reputation: 1869Reputation: 1869Reputation: 1869Reputation: 1869Reputation: 1869Reputation: 1869Reputation: 1869Reputation: 1869
@OP: When in doubt, do examine the question before asking for help. The assembly listing (-l option) might be very useful.
Example source:
Code:
        welcome db "Hello, World!",0x0a
        goodbye db "Goodbye, World!", 0x0a
        main db "What's Up",0x0a
        mainLength equ $ - main
        welcomeLength equ $ - welcome
        goodbyeLength equ $ - goodbye

	dw mainLength
	dw welcomeLength
	dw goodbyeLength
Example listing:
Code:
     1                                  section .data
     2 00000000 48656C6C6F2C20576F-             welcome db "Hello, World!",0x0a
     2 00000009 726C64210A         
     3 0000000E 476F6F646279652C20-             goodbye db "Goodbye, World!", 0x0a
     3 00000017 576F726C64210A     
     4 0000001E 576861742773205570-             main db "What's Up",0x0a
     4 00000027 0A                 
     5                                          mainLength equ $ - main
     6                                          welcomeLength equ $ - welcome
     7                                          goodbyeLength equ $ - goodbye
     8                                  
     9 00000028 0A00 means 10                 	dw mainLength
    10 0000002A 2800 means 40                  	dw welcomeLength
    11 0000002C 1A00 means 26                  	dw goodbyeLength
 
Old 11-09-2017, 08:44 AM   #6
sundialsvcs
LQ Guru
 
Registered: Feb 2004
Location: SE Tennessee, USA
Distribution: Gentoo, LFS
Posts: 10,659
Blog Entries: 4

Rep: Reputation: 3939Reputation: 3939Reputation: 3939Reputation: 3939Reputation: 3939Reputation: 3939Reputation: 3939Reputation: 3939Reputation: 3939Reputation: 3939Reputation: 3939
But ... pursue this kind of "assembly language programming" only as an exercise in curiosity.

It used to be the case that "compilers spat out really-crappy code ... quickly." But no more. Today's microprocessors are designed to accept object-code that's produced by compilers which implement the specific logic, and which use the specific instructions, that their manufacturers carefully supply to compiler-writers (especially the gcc teams). Except for the most-trivial sequences of inline asm { ... } blocks, or truly-special cases like Linux's "trampoline" code, hand-coded assembler is no longer the best way to go.
 
Old 11-09-2017, 08:58 AM   #7
jlinkels
LQ Guru
 
Registered: Oct 2003
Location: Bonaire, Leeuwarden
Distribution: Debian /Jessie/Stretch/Sid, Linux Mint DE
Posts: 5,195

Rep: Reputation: 1043Reputation: 1043Reputation: 1043Reputation: 1043Reputation: 1043Reputation: 1043Reputation: 1043Reputation: 1043
Good to see good ol' assembly language again.

In other answers the string addressing error was pointed out. However, you also use the RET instruction without a CALL instruction.

Calling a function is something entirely different from using the JMP instruction. The JMP instruction loads the address referred to in the JMP instruction in the program counter. And that is it.

The CALL instruction also jumps to that address, but in addition pushes the address of the next instruction on the stack. The RET instruction pops that address and jumps to it. So if you use a RET without a CALL, nonsense is popped off the stack. Proper function calls use CALL/RET because that is the only ordered way for nested function calls.

Note that the CALL instruction may also be named JSR.

This mechanism also requires that your stack pointer is properly initialized. If not, you don't have a stack and cannot put the return address there.

If you want to do it really nice, you set up a stack frame, and you allocate all variables used in the function on the stack as well. And function parameters should be passed either on stack or in registers. But that is up to you, depending on how efficient you want your code to run.

jlinkels
 
1 members found this post helpful.
Old 11-10-2017, 05:38 PM   #8
dogpatch
Member
 
Registered: Nov 2005
Location: Central America
Distribution: Mepis, Android
Posts: 490
Blog Entries: 4

Rep: Reputation: 238Reputation: 238Reputation: 238
Quote:
Originally Posted by tpalmerstudios View Post
Thanks dogpatch. That solved my problem. The first issue with the size of the strings, why is that a problem? Does '$' refer to the variable before it?
'$' refers to the current offset in the process of assembling. So in your code
Code:
        welcome db "Hello, World!",0x0a
        goodbye db "Goodbye, World!", 0x0a
        main db "What's Up",0x0a
        mainLength equ $ - main
        welcomeLength equ $ - welcome
        goodbyeLength equ $ - goodbye
the assembler calculates the value of 'welcomeLength' by subtracting the offset of the 'welcome' literal from the current offset. Since, as you have coded it, the current offset for the 'welcomelength' definition comes after all 3 literals have been defined, all three literals are made part of the calculated length.

Sorry for not answering sooner; I was offline for a couple days

Last edited by dogpatch; 11-10-2017 at 05:40 PM.
 
1 members found this post helpful.
  


Reply

Tags
assembly-language, low-level, nasm, programming, x86_64



Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is Off
HTML code is Off



Similar Threads
Thread Thread Starter Forum Replies Last Post
arrays of function pointers on x86 assembly micflunu Linux - Kernel 3 07-25-2016 10:50 AM
calling a c function from a NASM assembly file micflunu Linux - Newbie 8 07-07-2016 01:31 PM
Using system calls to create/context switch threads in assembly code casmac Programming 1 07-13-2007 04:48 PM
function calls inside a function manas_sem Programming 2 02-28-2007 01:27 AM
Tracing function calls... How? ik_nitk Programming 3 06-05-2006 07:05 AM

LinuxQuestions.org > Forums > Non-*NIX Forums > Programming

All times are GMT -5. The time now is 04:42 PM.

Main Menu
Advertisement
My LQ
Write for LQ
LinuxQuestions.org is looking for people interested in writing Editorials, Articles, Reviews, and more. If you'd like to contribute content, let us know.
Main Menu
Syndicate
RSS1  Latest Threads
RSS1  LQ News
Twitter: @linuxquestions
Open Source Consulting | Domain Registration