[comp.sources.wanted] What does this assembler code do?

ralph@laas.fr (Ralph P. Sobek) (12/04/90)

The following embedded assembler code belongs to some C language code
for reading VAX VMS Backup tapes under Unix.  Maybe this would compile
under Ultrix.  If someone can translate this into straight C, I would
sure appreciate that, also.  Here's the function:
 
vdatetosec()
{
	asm("movl 4(ap),r0");
	asm("movl (r0)+,r2; movl (r0),r3; subl2 $2913970176,r2; sbwc $8164719,r3 ");
	asm("ediv $10000000,r2,r0,r1");
}

Neither SPARCs nor 680x0s like this code!

--
Ralph P. Sobek			  Disclaimer: The above ruminations are my own.
ralph@laas.fr				   Addresses are ordered by importance.
ralph@laas.uucp, or ...!uunet!laas!ralph		
If all else fails, try:				      sobek@eclair.Berkeley.EDU
===============================================================================
Reliable software should kill people reliably! -Andy Mickel, Pascal News #13,78

) (12/05/90)

In article <RALPH.90Dec4163345@orion.laas.fr> ralph@laas.fr writes:
>The following embedded assembler code belongs to some C language code
>for reading VAX VMS Backup tapes under Unix.  Maybe this would compile
>under Ultrix.  If someone can translate this into straight C, I would
>sure appreciate that, also.  Here's the function:
> 
>vdatetosec()
>{
>	asm("movl 4(ap),r0");
>	asm("movl (r0)+,r2; movl (r0),r3; subl2 $2913970176,r2; sbwc $8164719,r3 ");
>	asm("ediv $10000000,r2,r0,r1");
>}
>
>Neither SPARCs nor 680x0s like this code!
>
>--
>Ralph P. Sobek			  Disclaimer: The above ruminations are my own.
>ralph@laas.fr				   Addresses are ordered by importance.
>ralph@laas.uucp, or ...!uunet!laas!ralph		
>If all else fails, try:				      sobek@eclair.Berkeley.EDU
>===============================================================================
>Reliable software should kill people reliably! -Andy Mickel, Pascal News #13,78

Newsgroups: comp.sources.wanted
Subject: Re: What does this assembler code do?
Summary: 
Expires: 
References: <RALPH.90Dec4163345@orion.laas.fr>
Sender: 
Followup-To: 
Distribution: comp
Organization: Georgia Institute of Technology
Keywords: VAX, VMS, backup

In article <RALPH.90Dec4163345@orion.laas.fr> ralph@laas.fr writes:
>The following embedded assembler code belongs to some C language code
>for reading VAX VMS Backup tapes under Unix.  Maybe this would compile
>under Ultrix.  If someone can translate this into straight C, I would
>sure appreciate that, also.  Here's the function:
> 
>vdatetosec()
>{
>	asm("movl 4(ap),r0");
>	asm("movl (r0)+,r2; movl (r0),r3; subl2 $2913970176,r2; sbwc $8164719,r3 ");
>	asm("ediv $10000000,r2,r0,r1");
>}
>
>Neither SPARCs nor 680x0s like this code!
>
first note: I treid to reply through mail, but my machine didn't like the
address.

The reason that doesn't work on non-DEC machines is that
the assembler is machine specific.. and thus only works on
Dec machines.. not on sparc's, not on 68K's, just on Dec's.

See, most C compilers (esp. on unix) don't output executable,
they output assembly code, which then gets passed to an assembler
(this is transparent to you.. but there's an option to get it to
stop in the middle).. all the "asm()" function does is say
to the compiler "pass this text directly to the assembler"

well.. basically  :)


Hmm..  the actual code isn't too clear..


>	asm("movl 4(ap),r0");
ok.. movl means move a long word.. this instruction is saying
   "take the longword at ap+4 (using the ap as a pointer),
    and move it to the zero register (r0)"
      parenthesis means indirection.
   here's where the fun comes in..  ap is the argument pointer
   for "calls" functions in vax assembler.. all arguments are
   long words.. and all addresses are bytes.. thus ap+4 is
   the FIRST argument.


>	asm("movl (r0)+,r2; movl (r0),r3; subl2 $2913970176,r2; sbwc $8164719,r3 ");
  ok.. (r0)+ means use r0 as a pointer, and post imcrement it.. 
  so.. the first two instrucions basically say "take what the first
  argument points to, move it to r2, take the next thing after that,
  and move it to r3).. since this is a movl, the post increment  is
  automatically by 4
  it could equivilently have been "movl (r0), r2; movl 4(r0),r3"
  with the small exception that r0 wwould still be pointing at
  r2, and not at r3.
  subl2 is subract longwords, 2 arguments.  So, it's the same as
  r2 = r2 - $2913970176 (decimal)
  sbwc is subract with carry

>	asm("ediv $10000000,r2,r0,r1");

  ediv is extended devision..and, unfortunately, I don't have the
  argument in my brain anymore.. oh..heh.. the TA for the assembler
  class we have here just came in (our class was in VAX assembler).

   ediv bottom, top, answer, remainder

   also, top is a QUAD word.. so it'd be r3,r2 concatinated..r3
   being the most significant bits.

   r0 = r3r2 / $10000000
   r1 = r3r2 % $10000000    (in C..where all are int)

if it weren't for the direct use of registers, I'd probably be
able to make this into soem C code.. unfortunately, I can't...
I'll send this to said TA.. but he's REALLY busy right now, so
he might not get back to you until MUCH later.

Jon: this is off of comp.sources.wanted

John
-- 
   Emporers Thought for the Day:                |       John E. Rudd jr.
Only the insane have the strength to prosper;   |  ccastjr@prism.gatech.edu
   Only those who prosper judge what is sane.   |  (ex- kzin@ucscb.ucsc.edu)
#include<std.disclaim>  Send all comments, flames, and complaints to /dev/null.

brendan@cs.widener.edu (Brendan Kehoe) (12/05/90)

In <RALPH.90Dec4163345@orion.laas.fr>, ralph@laas.fr writes:
>vdatetosec()
>{
>	asm("movl 4(ap),r0");
>	asm("movl (r0)+,r2; movl (r0),r3; subl2 $2913970176,r2; sbwc $8164719,r3 ");
>	asm("ediv $10000000,r2,r0,r1");
>}
>Neither SPARCs nor 680x0s like this code!

 That's because it's Vax MACRO-32 code. It's hard to tell *what* it
does because of the two addresses (used by subl2 & sbwc). Maybe a VMS
guru can give you a better hint.
 I really don't think this belongs over here...



-- 
    Brendan Kehoe - Widener Sun Network Manager - brendan@cs.widener.edu
 Widener University in Chester PA              A Bloody Sun-vs-Dec War Zone
  "Hi there! Did you know that the very same technology that cleaned up the
Alaskan oil spill can be used to suck the fat out of your thighs & upper lip?"

graham@smaug.enet.dec.com (12/05/90)

In article <RALPH.90Dec4163345@orion.laas.fr>, ralph@laas.fr (Ralph P. Sobek)
writes:
|>The following embedded assembler code belongs to some C language code
|>for reading VAX VMS Backup tapes under Unix.  Maybe this would compile
|>under Ultrix. 

It appears to convert a 64-bit absolute VMS time value (the address of which is
passed
as the first parameter to the routine) into the number of seconds since 1am on
1-JAN-1970!

It does this by subtracting 0x007C956FADAFA800 ( 1-JAN-1970 01:00:00.00) from
the time
value passed and dividing the result by 10,000,000

rcb@ccpv1.cc.ncsu.edu (Randy Buckland) (12/05/90)

ralph@laas.fr (Ralph P. Sobek) writes:
>vdatetosec()
>{
>	asm("movl 4(ap),r0");
>	asm("movl (r0)+,r2; movl (r0),r3; subl2 $2913970176,r2; sbwc $8164719,r3 ");
>	asm("ediv $10000000,r2,r0,r1");
>}

VMS uses 64-bit integers to store the time value. It is the number of
100 nanosecond intervals since nov 17, 1858 00:00:00.00 

This code expects a the address of the 64bit time parameter as the only 
parameter to the function. It load it into 2 registers, subtracts a constant
(probably the diff between 1858 and jan 1, 1970) and divides to get seconds.

In other words, it converts a vms time to a unix time.

--
Randy Buckland						"It's hard to work
North Carolina State University				in a group when you're
randy@ncsu.edu (919) 737-2517				omnipotent"	-- Q

cox@software.org (Guy Cox) (12/07/90)

In article <RALPH.90Dec4163345@orion.laas.fr> ralph@laas.fr writes:
> The following embedded assembler code belongs to some C language code
> for reading VAX VMS Backup tapes under Unix.  Maybe this would compile
> under Ultrix.  If someone can translate this into straight C, I would
> sure appreciate that, also.  Here's the function:
>  
> vdatetosec()
> {
> 	asm("movl 4(ap),r0");
> 	asm("movl (r0)+,r2; movl (r0),r3; subl2 $2913970176,r2; sbwc $8164719,r3 ");
> 	asm("ediv $10000000,r2,r0,r1");
> }
> 
> Neither SPARCs nor 680x0s like this code!
> 
> --
> Ralph P. Sobek			  Disclaimer: The above ruminations are my own.
> ralph@laas.fr				   Addresses are ordered by importance.
> ralph@laas.uucp, or ...!uunet!laas!ralph		
> If all else fails, try:				      sobek@eclair.Berkeley.EDU
> ===============================================================================
> Reliable software should kill people reliably! -Andy Mickel, Pascal News #13,78

 The first instruction load the first argument into register 0. ( it looks like a pointer to me).

 the second is an autoincrement move from the location now contained in reg 0 to reg 2. The 
 pointer in reg 0 is increment by 4 after the move.
 
 the contents pointed to by the new pointer in reg 0 are moved to reg 3.

 now a long subtraction of the hex value to the contents of reg 2. ( obviously some
 kind of "magic" number.

  now a subtract with carry of the hex value from reg 3. ( another magic number ?).

  and finally an extended divide of the $10000000 into the quadword r2-r3 with the quotient
   going into r0 and the remainder going into r1.

  It's pretty straight forward except for the magic numbers .

--
//
//Remember; Tuesday is Soylent green day!
//

Guy O. Cox, Jr.  
Software Productivity Consortium.
2214 RockHill Rd
Herndon, VA 22090
703-742-7219
cox@software.org