How to safely and reasonably convert a float or double to string or char array?

"__ftoa_engine" is an internal function which IDE does not let me use it.

I just showed you how to use it...

extern "C" int __ftoa_engine (double val, char *buf, unsigned char prec, unsigned char maxdgs);

there is no way over hear to write assembly code which takes variables from outside in Arduino IDE. let's say I have "uint8_t a;" how do I use this in my assembly code?

Of course there is. This (along with dtostr() itself) is avr-gcc and C compiler stuff, and not "arduino stuff", so you have to expand your search. Dealing with "uint8_t a" depends on exactly where it is. If it's a function parameter, it will show up in one of the AVR registers (which one is based on its position in the parameter list.) If it's global, it accessible via name.
See Frequently Asked Questions
Try this for a starter (test.ino)

#include <stdio.h>
FILE* ser;
extern "C" int __ftoa_engine (double val, char *buf, unsigned char prec, unsigned char maxdgs);

int fput(char c, FILE* f) {
  Serial.write( c);
  return 0;
}

void setup() {
  Serial.begin(9600);
  stdout = fdevopen(fput, NULL);
}

char buffer[20];
void ftoa_eng_study(float f)
{
  memset(buffer, 0, sizeof(buffer));
  int8_t exponent = __ftoa_engine(f, buffer, 8, 19);
  printf("Floating input according to Serial.print(): ");
  Serial.println(f, 8);
  printf("   engine Exponent: %d, flags 0x%02x Digits: ", exponent, buffer[0]);
  for (byte i = 1; i < 20; i++) {
    if (buffer[i] == 0) break;
    Serial.write(buffer[i]);
  }
  Serial.println();
  Serial.println();
}

void loop ()
{
  ftoa_eng_study(PI);
  ftoa_eng_study(987.654e20);
  ftoa_eng_study(42.0);
  ftoa_eng_study(6.626e-34);

  Serial.println();
  delay(10000);
}

(Code modified. Hmm. I don't know that I understand what happened to Plank's constant!)