ProgrammingThis forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game.
Notices
Welcome to LinuxQuestions.org, a friendly and active Linux Community.
You are currently viewing LQ as a guest. By joining our community you will have the ability to post topics, receive our newsletter, use the advanced search, subscribe to threads and access many other special features. Registration is quick, simple and absolutely free. Join our community today!
Note that registered members see fewer ads, and ContentLink is completely disabled once you log in.
If you have any problems with the registration process or your account login, please contact us. If you need to reset your password, click here.
Having a problem logging in? Please visit this page to clear all LQ-related cookies.
Get a virtual cloud desktop with the Linux distro that you want in less than five minutes with Shells! With over 10 pre-installed distros to choose from, the worry-free installation life is here! Whether you are a digital nomad or just looking for flexibility, Shells can put your Linux machine on the device that you want to use.
Exclusive for LQ members, get up to 45% off per month. Click here for more info.
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.
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?
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.
Distribution: Debian /Jessie/Stretch/Sid, Linux Mint DE
Posts: 5,195
Rep:
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.
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
LinuxQuestions.org is looking for people interested in writing
Editorials, Articles, Reviews, and more. If you'd like to contribute
content, let us know.