gas call/ret problem?

I am finding that the assembler “call” and “ret” functions in the IPL
code I am writing (taking cues from the source supplied by QSSL) for an x86
do not work. I.e., the “ret” fails. Has anyone reported a problem
with QNX Momentics and these calls when making 16-bit ROM images?

Richard B.

Richard Bonomo,6289 Chamberlin,263-4683, <bonomo@sal.wisc.edu> wrote:

I am finding that the assembler “call” and “ret” functions in the IPL
code I am writing (taking cues from the source supplied by QSSL) for an x86
do not work. I.e., the “ret” fails. Has anyone reported a problem
with QNX Momentics and these calls when making 16-bit ROM images?

Richard B.

Here’s a snippet of some 16 bit GNU assembler code for x86, which I think
addresses your problem. Note the .code16gcc directive, along with the
RETN (return near) macro, which is used instead of the actual ret
instruction. This is taken from the BIOS extension IPL code of the
SC400 BSP.

…text
.code16gcc
.align 2
.globl _start
…macro RETN
.byte 0xcb
…endm

_start: .byte 0x00,0x00,0x00,0x00,0x00,0x00
L1:
movw $0x0000,%ax
movw %ax,%es
movw $L2,%ax
xchgw %es:(0x00000064),%ax
movw %ax,%es:(0x000003e0)
movw %cs,%ax
xchgw %es:(0x00000066),%ax
movw %ax,%es:(0x000003e2)
RETN

\

David Green (dgreen@qnx.com)

QNX Software Systems Ltd.
http://www.qnx.com

Dave Green wrote:

Richard Bonomo,6289 Chamberlin,263-4683, <> bonomo@sal.wisc.edu> > wrote:
I am finding that the assembler “call” and “ret” functions in the IPL
code I am writing (taking cues from the source supplied by QSSL) for an
x86
do not work. I.e., the “ret” fails. Has anyone reported a problem
with QNX Momentics and these calls when making 16-bit ROM images?

Richard B.

Here’s a snippet of some 16 bit GNU assembler code for x86, which I think
addresses your problem. Note the .code16gcc directive, along with the
RETN (return near) macro, which is used instead of the actual ret
instruction. This is taken from the BIOS extension IPL code of the
SC400 BSP.

.text
.code16gcc
.align 2
.globl _start
.macro RETN
.byte 0xcb
.endm

_start: .byte 0x00,0x00,0x00,0x00,0x00,0x00
L1:
movw $0x0000,%ax
movw %ax,%es
movw $L2,%ax
xchgw %es:(0x00000064),%ax
movw %ax,%es:(0x000003e0)
movw %cs,%ax
xchgw %es:(0x00000066),%ax
movw %ax,%es:(0x000003e2)
RETN
Dear Dave,

Thanks for responding! I take it, then, that this is a well-known problem…
Two requests:

  1. Could you point me to some place where this problem with the ret call in
    16-bit code is described and discussed?

  2. Could you elucidate your suggestion a bit? I see RETN is defined as
    having an opcode of 0xcb, which normally corresponds to a “far return”
    according to my reference. Can this be used in tandem with a “call”
    opcode, or does one have to manipulate the registers and pc “manually”
    to use it? (I did give a quick “dumb” test, with no luck, so I take it
    more has to be done than simply substitute it for a plain “ret” opcode…)

Thanks!

Rich

Richard Bonomo,6289 Chamberlin,263-4683, <bonomo@sal.wisc.edu> wrote:

Dave Green wrote:

Richard Bonomo,6289 Chamberlin,263-4683, <> bonomo@sal.wisc.edu> > wrote:
I am finding that the assembler “call” and “ret” functions in the IPL
code I am writing (taking cues from the source supplied by QSSL) for an
x86
do not work. I.e., the “ret” fails. Has anyone reported a problem
with QNX Momentics and these calls when making 16-bit ROM images?

Richard B.

Here’s a snippet of some 16 bit GNU assembler code for x86, which I think
addresses your problem. Note the .code16gcc directive, along with the
RETN (return near) macro, which is used instead of the actual ret
instruction. This is taken from the BIOS extension IPL code of the
SC400 BSP.

.text
.code16gcc
.align 2
.globl _start
.macro RETN
.byte 0xcb
.endm

_start: .byte 0x00,0x00,0x00,0x00,0x00,0x00
L1:
movw $0x0000,%ax
movw %ax,%es
movw $L2,%ax
xchgw %es:(0x00000064),%ax
movw %ax,%es:(0x000003e0)
movw %cs,%ax
xchgw %es:(0x00000066),%ax
movw %ax,%es:(0x000003e2)
RETN
Dear Dave,
Thanks for responding! I take it, then, that this is a well-known problem…
Two requests:

  1. Could you point me to some place where this problem with the ret call in
    16-bit code is described and discussed?

There is a discussion of the issue at:

http://www.gnu.org/manual/gas-2.9.1/html_node/as_203.html

A google of “GAS 16 bit code” also turns up plenty of other hits…

If you have the x86 BSP, take a look at:

/usr/src/bsp/6.2.x/x86/bios/src/hardware/startup/bootfile/x86-o/bios.s

which intermixes 16 and 32 bit code, and has various macros to
handle calls, rets, and jumps within this code.

  1. Could you elucidate your suggestion a bit? I see RETN is defined as
    having an opcode of 0xcb, which normally corresponds to a “far return”
    according to my reference. Can this be used in tandem with a “call”
    opcode, or does one have to manipulate the registers and pc “manually”
    to use it? (I did give a quick “dumb” test, with no luck, so I take it
    more has to be done than simply substitute it for a plain “ret” opcode…)

Thanks!

Rich

David Green (dgreen@qnx.com)

QNX Software Systems Ltd.
http://www.qnx.com