LinuxQuestions.org

LinuxQuestions.org (/questions/)
-   Linux - Software (https://www.linuxquestions.org/questions/linux-software-2/)
-   -   GNU Assembler (GAS/"as"): How to emit 8 bit relative branches? (https://www.linuxquestions.org/questions/linux-software-2/gnu-assembler-gas-as-how-to-emit-8-bit-relative-branches-934337/)

tedn 03-14-2012 12:06 AM

GNU Assembler (GAS/"as"): How to emit 8 bit relative branches?
 
I have a program (i386) which I have disassembled.

At one point, it has the byte sequence:
"67 75 61" which my disassembler renders as

"addr16 jne 0x00000064"

ie: as a 8-bit jump relative to the current program counter.

However, I am unable to get GNU as to emit an 8-bit relative jump when I try to do this from an assembler program.

If I run as on a file containing

"addr16 jne 0x00000064"

first of all it tells me "Warning: skipping prefixes on this instruction", and the actual code assembled into the object file is:

"0: 0f 85 60 00 00 00 jne 0x66"

That is, it has emitted a 32-bit jump.

I have been unable to find any way to get an 8-bit jump emitted other than using symbols, like

jne foo
nop
foo:
nop

which *will* emit an 8-bit jump, but I don't want to have to define symbols and may not have the information in the right place to do so any way -- I just want to be able to say

jne 0x10
or whatever and have that come out as an 8-bit relative jump.

Suggestions?

(This is on Ubuntu 10.04 with "as" 2.20.1, but I suspect applies on many i386/gas systems).

Thanks!

hydraMax 03-14-2012 07:21 PM

I find this question rather intriguing. I've spent about 45 minutes so far trying to find the answer but to no avail. I'll try to spend some more time on this tonight after I get home. If it helps, though:

* What you are looking for is a "short jump" as opposed to a "near jump". It states in the AMD64 AMP vol 1 that short jumps exist (for amd64, of course), but I haven't been able to find anything in the AS manual on it yet.

* You can, at least, use invisible local symbols. They are defined with a '.L' prefix, but don't actually show up in the output:

Code:

$ cat test.S
.text
        jne .LF1
        nop
        nop
        nop
.LF1:
        nop
$ as test.S -o test.o
$ objdump -d test.o

test.o:    file format elf64-x86-64


Disassembly of section .text:

0000000000000000 <.text>:
  0:        75 03                        jne    0x5
  2:        90                          nop
  3:        90                          nop
  4:        90                          nop
  5:        90                          nop


tedn 03-15-2012 12:30 AM

Yeah, they're in the Intel manuals too, of course with the opcodes, but I can't seem to get those opcodes emitted except with the label hack. I figured there would be some size suffix to add to the instruction to tell it to do 8-bit jumps, but not so far as I see..

hydraMax 03-15-2012 06:50 PM

I communicated with the folks at the binutils mailing list. A user named Ian gave me the answer:

Code:

$ cat test.S
.text
        nop
        jmp .+5
        nop
        nop
        nop
        nop
        nop
        nop
$ as test.S -o test.o
$ objdump test.o -d

test.o:    file format elf64-x86-64


Disassembly of section .text:

0000000000000000 <.text>:
  0:        90                          nop
  1:        eb 03                        jmp    0x6
  3:        90                          nop
  4:        90                          nop
  5:        90                          nop
  6:        90                          nop
  7:        90                          nop
  8:        90                          nop

Same principle for jne, etc. It seems that GAS translates the operand to include the two instruction/operand bytes.

tedn 03-15-2012 10:16 PM

Hey, very cool, thanks!

I never would have guessed *that* was the incantation!


All times are GMT -5. The time now is 08:32 PM.