16-bit "call" not functioning -- ideas?

Greetings all!

For some time now, I have been wrestling with a machine-language program
which will eventually go in a boot PROM. I find that I am able to get it
to compile and load, but one big hangup is that I cannot get the "call
" macro to work.

I am using a 80486 processor, and an running in “real” mode. The
development seat is QNX Momentics PE (6.2.0) on an Intel box. The
pseudo-IPL image (what I am writing for the target 80486 processor)
is loaded into a PROM, which is then physically inserted into a
socket on the PC-104 board. I am able to write to either serial
line at will (this is my diagnostic). I can write repetitively
in an infinite loop using a “jmp” instruction, without problem.

However, If I try to use a “call” instruction, the program apparently
does not return. (I am not even sure it gets to the routine properly –
I am still checking on that.)

I have tried several things:

using .code16gcc (the usual case)
not using .code16gcc
using .code16
adding the “66” opcode prefix before the call or ret opcodes or both
wrapping the call and ret functions with .code32 directives
manually hacking the binary to modify call and return opcodes and
to do many other things to the binary.

Still, an invokation of “call” is a jump to oblivion, even though the
“routine” called is just a dummy with a couple of “nops” right now.

Is there an Intel x86 guru out there who can tell me what opcode pair
(equivalent to assembly call and ret) would definitely work in a 80486
which presumably wakes up in real (16-bit) mode?

Thanks!

Rich

Richard,

There are some code examples in the x86 bsp section of the Momentics
PE 6.2.0 which may help:

/usr/src/bsp-6.2.0/libs/src/hardware/ipl/lib/x86/protected.s

has an example of a near call macro, and:

/usr/src/bsp-6.2.0/x86/sc400/src/hardware/ipl/boards/sc400_ext/cstart_int19.s

has an example of a near ret macro.



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

Greetings all!

For some time now, I have been wrestling with a machine-language program
which will eventually go in a boot PROM. I find that I am able to get it
to compile and load, but one big hangup is that I cannot get the “call
label>” macro to work.

I am using a 80486 processor, and an running in “real” mode. The
development seat is QNX Momentics PE (6.2.0) on an Intel box. The
pseudo-IPL image (what I am writing for the target 80486 processor)
is loaded into a PROM, which is then physically inserted into a
socket on the PC-104 board. I am able to write to either serial
line at will (this is my diagnostic). I can write repetitively
in an infinite loop using a “jmp” instruction, without problem.

However, If I try to use a “call” instruction, the program apparently
does not return. (I am not even sure it gets to the routine properly –
I am still checking on that.)

I have tried several things:

using .code16gcc (the usual case)
not using .code16gcc
using .code16
adding the “66” opcode prefix before the call or ret opcodes or both
wrapping the call and ret functions with .code32 directives
manually hacking the binary to modify call and return opcodes and
to do many other things to the binary.

Still, an invokation of “call” is a jump to oblivion, even though the
“routine” called is just a dummy with a couple of “nops” right now.

Is there an Intel x86 guru out there who can tell me what opcode pair
(equivalent to assembly call and ret) would definitely work in a 80486
which presumably wakes up in real (16-bit) mode?

Thanks!

Rich

David Green (dgreen@qnx.com)
QNX Software Systems Ltd.
http://www.qnx.com

Dave Green wrote:

Richard,

There are some code examples in the x86 bsp section of the Momentics
PE 6.2.0 which may help:

/usr/src/bsp-6.2.0/libs/src/hardware/ipl/lib/x86/protected.s

has an example of a near call macro, and:


/usr/src/bsp-6.2.0/x86/sc400/src/hardware/ipl/boards/sc400_ext/cstart_int19.s

has an example of a near ret macro.



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

For some time now, I have been wrestling with a machine-language program
which will eventually go in a boot PROM. I find that I am able to get it
to compile and load, but one big hangup is that I cannot get the “call
label>” macro to work.

I am using a 80486 processor, and an running in “real” mode. The
development seat is QNX Momentics PE (6.2.0) on an Intel box. The
pseudo-IPL image (what I am writing for the target 80486 processor)
is loaded into a PROM, which is then physically inserted into a
socket on the PC-104 board. I am able to write to either serial
line at will (this is my diagnostic). I can write repetitively
in an infinite loop using a “jmp” instruction, without problem.

However, If I try to use a “call” instruction, the program apparently
does not return. (I am not even sure it gets to the routine properly –
I am still checking on that.)

I have tried several things:

using .code16gcc (the usual case)
not using .code16gcc
using .code16
adding the “66” opcode prefix before the call or ret opcodes or both
wrapping the call and ret functions with .code32 directives
manually hacking the binary to modify call and return opcodes and
to do many other things to the binary.

Still, an invokation of “call” is a jump to oblivion, even though the
“routine” called is just a dummy with a couple of “nops” right now.

Is there an Intel x86 guru out there who can tell me what opcode pair
(equivalent to assembly call and ret) would definitely work in a 80486
which presumably wakes up in real (16-bit) mode?

Thanks!

Rich


OK I dug up that macro. There are a few similar to that floating around the

source distribution. So far, no luck.

At this point, I am working on the level of machine code (not assembler)
trying to find the right combination of opcodes which will do the job.
The gnu compiler, left to its own devices, produces an “e8” opcode followed
by 32 bits of address. Since the processor is in 16-bit mode on boot up, it
expects only 16 bits of relative address, so it fouls up the computation the
locationof the next address to be executed. I find that I can fix this by
manually patching (either directly with an editor, or by macro) the binary
to truncate the relative address to 16 bits, and to move the opcode foward
2 bytes, filling in the gap with nops (opcode 90). This gets the program
to jump to the correct location when it executes, but the return still
eludes me. I am not sure how to verify that opcode e8 is indeed pushing
two bytes onto the stack, and that whatever opcode I use for ret (I think
the macro referenced above uses opcode cb) pops the corresponding 2 bytes
when called. I am currently reduced to trying various opcode and
operand/address prefix combinations until I (I hope) find the combination
which works. If anyone has intimate knowledge of this on the machine-code
level for the 80486 I would love to hear from him.

Rich

Richard Bonomo,6289 Chamberlin,263-4683, wrote:

No other takers on this one? Should I be trying a different newsgroup
entirely?