⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 rdf2ihx.c

📁 开源的nasm编译器源码,研究编译器原理很有帮且
💻 C
字号:
/* rdf2ihx: convert an RDOFF object file to Intel Hex format.  This is based   on rdf2bin.  Note that this program only writes 16-bit HEX. */#include <stdlib.h>#include <stdio.h>#include <string.h>#include "rdfload.h"#include "rdoff.h"#include "nasmlib.h"#include "symtab.h"long origin = 0;int align = 16;/* This function writes a single n-byte data record to of.  Maximum value   for n is 255. */static int write_data_record(FILE *of, int ofs, int nbytes,			     unsigned char *data){  int i, iofs;  unsigned int checksum;  iofs = ofs;  fprintf(of, ":%02X%04X00", nbytes, ofs);  checksum = 0;  for (i=0; i<nbytes; i++) {    fprintf(of, "%02X", data[i]);    ofs++;    checksum += data[i];  }  checksum = checksum +		/* current checksum */    nbytes +			/* RECLEN (one byte) */    ((iofs >> 8) & 0xff) +	/* high byte of load offset */    (iofs & 0xff);		/* low byte of load offset */  checksum = ~checksum + 1;  fprintf(of, "%02X\n", checksum&0xff);  return(ofs);}int main(int argc, char **argv){  rdfmodule *m;  int tmp;  FILE *of;  char *padding;  unsigned char *segbin[2];  int pad[2], segn, ofs, i;  long segaddr;  unsigned int checksum;  symtabEnt *s;  if (argc < 2) {    puts("Usage: rdf2ihx [-o relocation-origin] [-p segment-alignment] "	 "input-file  output-file");    return(1);  }  argv++, argc--;  while (argc > 2) {    if (strcmp(*argv,"-o") == 0) {      argv++, argc--;      origin = readnum(*argv, &tmp);      if (tmp) {	fprintf(stderr,"rdf2ihx: invalid parameter: %s\n",*argv);	return 1;      }    } else if (strcmp(*argv,"-p") == 0) {      argv++, argc--;      align = readnum(*argv, &tmp);      if (tmp) {	fprintf(stderr,"rdf2ihx: invalid parameter: %s\n",*argv);	return 1;      }    } else       break;    argv++, argc--;  }  if (argc < 2) {    puts("rdf2ihx: required parameter missing");    return -1;  }  m = rdfload(*argv);  if (!m) {    rdfperror("rdf2ihx",*argv);    return 1;  }  printf("relocating %s: origin=%lx, align=%d\n",*argv, origin, align);  m->textrel = origin;  m->datarel = origin + m->f.seg[0].length;  if (m->datarel % align != 0) {    pad[0] = align - (m->datarel % align);    m->datarel += pad[0];  } else {    pad[0] = 0;  }  m->bssrel = m->datarel + m->f.seg[1].length;  if (m->bssrel % align != 0) {    pad[1] = align - (m->bssrel % align);    m->bssrel += pad[1];  } else {    pad[1] = 0;  }  printf("code: %08lx\ndata: %08lx\nbss:  %08lx\n",	 m->textrel, m->datarel, m->bssrel);  rdf_relocate(m);  argv++;  of = fopen(*argv,"w");  if (!of) {    fprintf(stderr,"rdf2ihx: could not open output file %s\n",*argv);    return(1);  }  padding = malloc(align);  if (!padding) {    fprintf(stderr,"rdf2ihx: out of memory\n");    return(1);  }  /* write extended segment address record */  fprintf(of, ":02000002");	/* Record mark, reclen, load offset & rectyp				   fields for ext. seg. address record */  segaddr = ((origin >> 16) & 0xffff);	/* segment address */  fprintf(of, "%04X", (unsigned int)(segaddr & 0xffff));  checksum = 0x02 +		/* reclen */    0x0000 +			/* Load Offset */    0x02 +			/* Rectyp */    (segaddr & 0xff) +		/* USBA low */    ((segaddr >> 8) & 0xff);	/* USBA high */  checksum = ~checksum + 1;	/* two's-complement the checksum */  fprintf(of, "%02X\n", checksum & 0xff);  /* See if there's a '_main' symbol in the symbol table */  if ((s=symtabFind(m->symtab, "_main")) == NULL) {    printf("No _main symbol found, no start segment address record added\n");  } else {    printf("_main symbol found at %04x:%04x\n", s->segment, 	   (unsigned int)(s->offset & 0xffff));    /* Create a start segment address record for the _main symbol. */    segaddr = ((s->segment & 0xffff) << 16) + ((s->offset) & 0xffff);    fprintf(of, ":04000003");	/* Record mark, reclen, load offset & rectyp				   fields for start seg. addr. record */    fprintf(of, "%08lX", segaddr); /* CS/IP field */    checksum = 0x04 +		/* reclen */      0x0000 +			/* load offset */      0x03 +			/* Rectyp */      (segaddr & 0xff) +	/* low-low byte of segaddr */      ((segaddr >> 8) & 0xff) +	/* low-high byte of segaddr */      ((segaddr >> 16) & 0xff) + /* high-low byte of segaddr */      ((segaddr >> 24) & 0xff);	/* high-high byte of segaddr */    checksum = ~checksum + 1;	/* two's complement */    fprintf(of, "%02X\n", checksum & 0xff);  }  /* Now it's time to write data records from the code and data segments in.     This current version doesn't check for segment overflow; proper behavior     should be to output a segment address record for the code and data     segments.  Something to do. */  ofs = 0;  segbin[0] = m->t;  segbin[1] = m->d;  for (segn=0; segn<2; segn++) {    int mod, adr;    if (m->f.seg[segn].length == 0)      continue;    for (i=0; i+15<m->f.seg[segn].length; i+=16) {      ofs = write_data_record(of, ofs, 16, &segbin[segn][i]);    }    if ((mod=m->f.seg[segn].length & 0x000f) != 0) {      adr = m->f.seg[segn].length & 0xfff0;      ofs = write_data_record(of, ofs, mod, &segbin[segn][adr]);    }  }  /* output an end of file record */  fprintf(of, ":00000001FF\n");  fclose(of);  return 0;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -