Author Topic: syscall_exit doesn't seem to work  (Read 8229 times)

Offline Demented

  • Jr. Member
  • *
  • Posts: 7
syscall_exit doesn't seem to work
« on: October 16, 2017, 07:41:07 AM »
Hi everyone!
I'm very new to assembler but I'm having fun learning as I go.
However, I'm facing a weird problem. My program doesn't seem to exit. Here's the code:

Code: [Select]
section .data
msg1 db "Jump successful",0x0a
msg2 db "No jump occured",0x0a

len1 equ $-msg1
len2 equ $-msg2

section .text
global _start

_start:
mov dx,10
cmp dx,10
je _success

mov eax,4
mov ebx,1
mov ecx,msg2
mov edx,len2
int 0x80

mov eax,1
int 0x80

_success:
mov eax,4
mov ebx,1
mov ecx,msg1
mov edx,len1
int 0x80

mov eax,1
int 0x80

What I expect to happen is that after I've compared dx with 10, it jumps to 'sucessful', prints the message and exists.
What it actual does is:
Quote
$nasm -g -F dwarf -f elf64 test.asm; ld -m elf_x86_64 -o test.out test.o
$./test.out
Jump successful
No jump occured

Why is that? I'm not new to programming, but new to assembler. I'm expecting the program to exit, not to return to the rest of the program after jumping.

I'd appreciate if anyone has an idea.
Thanks!

Offline dreamCoder

  • Full Member
  • **
  • Posts: 107
Re: syscall_exit doesn't seem to work
« Reply #1 on: October 16, 2017, 09:23:56 AM »
Not on linux right now, but in assembly, a function return uses "ret". Except for tha main or start where it uses "exit" to system.
 

Offline Demented

  • Jr. Member
  • *
  • Posts: 7
Re: syscall_exit doesn't seem to work
« Reply #2 on: October 16, 2017, 11:05:37 AM »
Hi, thanks for your reply.
I'm not sure if you got me right. I'm not trying to return from a function, I'm trying to end the program from within a function. Although I'm calling syscall_exit, it doesn't work as intended. Instead of ending the program after I called mov eax,1 and int 0x80, the program jumps back and continues with the rest of the code.

Thanks!

Offline dreamCoder

  • Full Member
  • **
  • Posts: 107
Re: syscall_exit doesn't seem to work
« Reply #3 on: October 16, 2017, 01:42:55 PM »
Demented

You don't do that. the ESP contains the return address of the caller. int 80h (inside the callee) will refer to that value found on ESP (call stack) upon return. That's explains why your code isn't exiting (aka looping).

If you want that kind of effect, you can modify the "pushed" address from the caller's environment so that the exit address (on ESP) is pushed instead of the next instruction address.

Code: [Select]
_start:
     push esp
     call _callee

     mov ebx,0
     mov eax,1
     int 80h

_callee:
   
    add esp,4
    mov ebx,0
    mov eax,1
    int 80h

I don't have Linux to test it right now, so I am just giving you the idea / pseudocode on how to execute such plan. Many other techniques to consider.



     

Offline Demented

  • Jr. Member
  • *
  • Posts: 7
Re: syscall_exit doesn't seem to work
« Reply #4 on: October 16, 2017, 02:19:36 PM »
Hi!

Ah, that sounds logical. I didn't know this is the normal behavior.
I'll test your suggestion when I'm home later!

Thanks!

Offline Frank Kotler

  • NASM Developer
  • Hero Member
  • *****
  • Posts: 2667
  • Country: us
Re: syscall_exit doesn't seem to work
« Reply #5 on: October 16, 2017, 04:51:04 PM »
Hi Guys,

The first thing that jumps out at me is that you're calculating the length wrong:
Code: [Select]
section .data
msg1 db "Jump successful",0x0a
msg2 db "No jump occured",0x0a

len1 equ $-msg1
len2 equ $-msg2
"len1" gets the length of both messages... and therefore prints both messages. I suspect that's all that's wrong with your program. Put "len1" right after "msg1" and I think it'll work.

Also, you've got 32 bit code there and you're assembling it as 64 bit code. That will "probably" work. If you want 64 bit code, you probably want 64 bit system call numbers, put the parameters in 64 bit registers (rdi, rsi, rdx), and use "syscall" instead of "int 0x80".  I'm still running a 32 bit system, so I can't help you much there...

Best,
Frank


Offline Demented

  • Jr. Member
  • *
  • Posts: 7
Re: syscall_exit doesn't seem to work
« Reply #6 on: October 16, 2017, 05:58:09 PM »
Hi Guys,

The first thing that jumps out at me is that you're calculating the length wrong:
Code: [Select]
section .data
msg1 db "Jump successful",0x0a
msg2 db "No jump occured",0x0a

len1 equ $-msg1
len2 equ $-msg2
"len1" gets the length of both messages... and therefore prints both messages. I suspect that's all that's wrong with your program. Put "len1" right after "msg1" and I think it'll work.

Also, you've got 32 bit code there and you're assembling it as 64 bit code. That will "probably" work. If you want 64 bit code, you probably want 64 bit system call numbers, put the parameters in 64 bit registers (rdi, rsi, rdx), and use "syscall" instead of "int 0x80".  I'm still running a 32 bit system, so I can't help you much there...

Best,
Frank


Hi Frank.
Wow, that actually fixed my problem. I guess I'll have to figure out what $-variable actually does.
Thank you very much!

Offline Frank Kotler

  • NASM Developer
  • Hero Member
  • *****
  • Posts: 2667
  • Country: us
Re: syscall_exit doesn't seem to work
« Reply #7 on: October 16, 2017, 06:15:53 PM »
Nasm actually uses '$' for several purposes. In this context, it means "here". If it's right after "msg1" then "here - address of msg1" is the length of msg1. If "here" is after both messages, "here - address of msg1" is the length of both messages...  so it looks like your code is going back and printing the "no jump occured" message. If it really didn't exit, you'd get a segfault  - comment out the exit and try it...

Incidentally, the "_start:" label is not called, it's jumped to, so there is no return address on the stack. The first thing is "argc". So attempting to "ret" won't work...

Best,
Frank


Offline Demented

  • Jr. Member
  • *
  • Posts: 7
Re: syscall_exit doesn't seem to work
« Reply #8 on: October 17, 2017, 03:31:20 AM »
Hi,

I find that a little confusing to be honest. So, just to make sure I'm getting this right.
$ in this context means: Count back from the beginning of this line to the beginning (the offset) of 'msg1' without the quotes.
Is that correct?

Thank you.

Offline Frank Kotler

  • NASM Developer
  • Hero Member
  • *****
  • Posts: 2667
  • Country: us
Re: syscall_exit doesn't seem to work
« Reply #9 on: October 17, 2017, 03:52:21 AM »
Well, '$' just means "here" - where we are now. "$ - msg1" means "count back" (or "count forward") to or from the beginning of "msg1". In a pinch, you can count characters with your finger (a digital computer :) ), but I find that Nasm makes fewer mistakes than I do.

This is what you had:
Code: [Select]
section .data
msg1 db "Jump successful",0x0a
msg2 db "No jump occured",0x0a

len1 equ $-msg1
len2 equ $-msg2

This is what you wanted:
Code: [Select]
section .data
msg1 db "Jump successful",0x0a
len1 equ $-msg1

msg2 db "No jump occured",0x0a
len2 equ $-msg2

I think you've got it right.

Best,
Frank


Offline Demented

  • Jr. Member
  • *
  • Posts: 7
Re: syscall_exit doesn't seem to work
« Reply #10 on: October 17, 2017, 04:46:49 AM »
Well, '$' just means "here" - where we are now. "$ - msg1" means "count back" (or "count forward") to or from the beginning of "msg1". In a pinch, you can count characters with your finger (a digital computer :) ), but I find that Nasm makes fewer mistakes than I do.
Hi Frank,

I think that is what's confusing me.
Code: [Select]
msg1 db "Jump successful",0x0a
len1 equ $-msg1
If I interprete $ as 'here' (as in: this exact position on this line) and count back to the beginning of 'msg1', I end up with a number larger than the actual string. To be exact: In this example I'd count 9 (length of 'len1 equ $') + 18 (length of 'Jump sucessful",0xa') and end up with a total length of 27, which of course isn't correct. So, 'here' actually refers to the beginning of the line in which $ is in, right?

It seems to sound pretty simple to most people, but to me it sounds like $ does something different than explained.

Thank you for your patience. I hope I'm not being annoying or making a total idiot out of myself :)
« Last Edit: October 17, 2017, 04:55:35 AM by Demented »

Offline Frank Kotler

  • NASM Developer
  • Hero Member
  • *****
  • Posts: 2667
  • Country: us
Re: syscall_exit doesn't seem to work
« Reply #11 on: October 17, 2017, 05:23:49 AM »
Yeah, "beginning of line" is correct. In this case, "len1 equ $ - msg1" doesn't emit any code at all So it doesn't count as part of the length of the string.

My "digital computer" only gets 16 for the length. Depends on whether you spell it "sucessful" or "successful". This is why I like to let Nasm do the complicated stuff - like counting...

In any case, if it seems confusing, I'm not explaining it well.

Best,
Frank


Offline Demented

  • Jr. Member
  • *
  • Posts: 7
Re: syscall_exit doesn't seem to work
« Reply #12 on: October 17, 2017, 05:46:49 AM »
You're doing a great job. I just needed to make sure I get it right. And I think I got it now!
I'll experiment with $ later today and come back here if there's still anything I don't understand.
Thank you very much!