0

I have a one line program in assembly

`jmp $

When compiling the program

nasm -f bin jmp$.s -o a.out

It generates a file a.out in binary. Seeing him with xxd a.out

00000000: ebfe

My understanding is that logically jmp $, for this particular case, should be the same as jmp -2 or jmp 0. Compiling both cases and looking shows me

00000000: e9fb ff

Which effectively do the same logically, but take up a bit more. According to the intel manual vol 2 chapter 3 section 3.3 jmp. The difference of the two is that one is that BE is JMP rel8 and E9m is JMP rel16.

My goal is that I don't want to use assembler directives, I just want to use assembly Intructions and I want to make the shortest bitwise statement possible. I want ebfe as a result but without using directives, what should I do? Please. Thanks.

Nate Eldredge
  • 48,811
  • 6
  • 54
  • 82
  • You had the masm tag which I assume was a typo, so I changed it. If this is not correct, please clarify. – Nate Eldredge Jul 12 '23 at 16:58
  • 2
    `jmp $` is the normal way to write it. It's a relative jump, but NASM doesn't AFAIK have syntax for specifying the `rel8` directly. `jmp -2` is assembled as a jump to absolute address `-2`. For relative addressing, you want stuff relative to `$`, the address of the start of this source line. So `jmp $ + 0` = `jmp $` is a jump to itself. – Peter Cordes Jul 12 '23 at 17:02
  • 2
    And if you want to give the displacement explicitly, then just put a label on the following line and add or subtract from it. So to get `eb 5a`, you can do `jmp nextline+0x5a` / `nextline: ...` – Nate Eldredge Jul 12 '23 at 17:06
  • 1
    The reason you get `e9 rel16=-4` is I think something to do with NASM's assumptions about absolute addresses. In the case of a `.bin` output file, NASM is also acting as a linker, but NASM's internals might favour using a full-width relative displacement when the absolute destination is specified. – Peter Cordes Jul 12 '23 at 17:07
  • @Nate Eldredge You are rigth! – Dipsie Camila Jul 12 '23 at 19:27
  • @Peter Cordes Thank for your answer, I think the same. Anyway if someone knows the answer, please let me know. – Dipsie Camila Jul 12 '23 at 19:29
  • 1
    At this point I am not sure what part of your question remains unanswered. Can you clarify? What exactly do you want to accomplish, and under what constraints? What is the context of the larger problem you are trying to solve? Also, I am not sure what you mean by "without using directives". Are things like `jmp short foo` acceptable? – Nate Eldredge Jul 12 '23 at 19:34
  • 1
    Is it just that you don't like `$` for some reason (but I don't understand why you wouldn't)? You can also do it with a label: `foo: jmp foo`. – Nate Eldredge Jul 12 '23 at 19:36
  • @Nate Eldredge My general goal is to program with pure assembly without assembler directives nor instructions such as labels, sections, define, include, times, org, $, etc. A particular case is being able to make an infinite loop with only two bytes. I figured I could do jmp -2 but it gives me three bytes and that equates to 50% slower. How can I write a loop that jumps to the beginning using only instructions contained in the intel manual Vol 2 chap 2 and consumes only two bytes? Thank for your concer and help, – Dipsie Camila Jul 13 '23 at 03:30
  • Well, I frankly don't understand why you would want to set yourself such odd constraints. But if you do, and you still want to use nasm, then I guess the answer is "you can't". Unless you also want to do the encoding by hand, and just write `db 0xeb, 0xfe`. I would say that symbolic labels are a central feature of assembly language, so it's not surprising that assemblers become basically unusable if you refuse to work with labels. – Nate Eldredge Jul 13 '23 at 06:57
  • 1
    I think maybe you missed Peter's point that the problem with `jmp -2` isn't just that it's three bytes, it's that it jumps to *the wrong address*. The assembler encodes a jump to absolute offset -2, i.e. `0xfffe`, by computing a displacement from what it knows to be the current address (which is really just an internal use of `$`). Your `jmp 0` probably looked right because it was the only instruction in your source file, and so it happened to actually be at address 0. – Nate Eldredge Jul 13 '23 at 07:02
  • Thank you all! @Nate Eldredge and Peter Cordes This is already solved. I appreciate your answers. – Dipsie Camila Jul 13 '23 at 11:15
  • @Peter Cordes Thanks! – Dipsie Camila Jul 13 '23 at 11:55
  • *equates to 50% slower* - Yes, 50% slower to fetch on 8088, but even there a taken jmp is slow enough (15 cycles) that it would *not* be 50% slower in cycles per iteration. On 8086 with its 16-bit bus, an extra byte might come for free or might need one extra fetch cycle if the start of the instruction was 2-byte aligned. [Why is LOOP faster than DEC,JNZ on 8086?](https://stackoverflow.com/q/71117163) / https://www2.math.uni-wuppertal.de/~fpf/Uebungen/GdR-SS02/opcode_i.html – Peter Cordes Jul 13 '23 at 17:33
  • Worst case scenario you can just insert `dw 0xebfe` where you want it. – puppydrum64 Jul 20 '23 at 15:35

0 Answers0