www.delorie.com/archives/browse.cgi   search  
Mail Archives: djgpp/1995/02/03/04:53:48

Date: Fri, 3 Feb 1995 03:58:48 -0400 (AST)
From: Bill Davidson <bdavidson AT ra DOT isisnet DOT com>
Subject: bugs in as
To: djgpp AT sun DOT soe DOT clarkson DOT edu

Well, not really; there's bugs and there's bugs.  Also, I know this isn't 
a djgpp issue but a GNU issue but I am not sure where to post this, and 
the 'as' info files don't seem to list a bug-reporting site.  As well, 
this might be of interest to djgpp newbies who are porting some assembly 
code.

I recently ported a program I wrote in Turbo C which uses one function 
written in assembler (mostly 80x87) to djgpp.  I read the 'as' docs 
before porting the assembler file and noted the different operand 
ordering etc.  Everything compiled/assembled fine, but the program didn't 
run correctly.

Most 80x8[67] assemblers (Intel, Microsoft, Borland, A86, etc.) support 
certain FP instruction "short forms" to simplify a few common 
operations.  For example, it is not unusual to load two numbers into the 
'87 register stack, perform an add or multiply or whatever, write the 
result to memory, and clean up the stack.  To simplify this we can use 
(Intel style) code like the following:
	fld	[ebp-8]
	fld	[ebp-16]
	fadd
	fstp	_result
The 'fadd' all by itself means "st(1) = st(1)+st(0), pop" (short form 
of faddp st(1), st(0)), so the result is in st(0) and the operands are not 
on the register stack.  Similarly with the "solo" versions of fsub, fmul, 
etc.  However, the same code assembled with as yields fadd %st(0), 
%st(1), which means "st(1) = %st(1)+%st(0)" (NOTE no pop, one operand 
remains on stack, result is not in stack top).

Not only is this behaviour disjoint from every other '86/87 assembler out 
there, it will seriously break code and IS NOT DOCUMENTED in the info 
files.  Further, why would one want a short form for an operation that is 
seldom used?  In other words, to replace the above code and still use 
the short form we have to write:
	fldl	-8(%ebp)
	fldl	-16(%ebp)
	fadd
	fpop
	fstl	_result
or else replace the fadd with faddp %st(0), %st(1).

What's worse, subtraction (and I assume division) also get their operands 
reversed, so I have to replace 'fsub' with 'fsubrp %st(0), %st(1)'.  This 
is not intuitive behaviour!

Finally, and as an aside, why doesn't gdb support the '87?  I can use 
edebug32 and get '87 support, or I can use gdb and forget about looking 
at the FP regs but get a more versatile debugger.  How hard would it be 
to upgrade gdb to show the '87 stack? (No, I haven't looked at the source 
yet.)

djgpp is a great package, but watch out for those FP gotcha's!

Bill Davidson
bdavidson AT ra DOT isisnet DOT com


- Raw text -


  webmaster     delorie software   privacy  
  Copyright © 2019   by DJ Delorie     Updated Jul 2019