日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

【转】hex和bin文件格式的区别

發布時間:2025/7/14 编程问答 19 豆豆
生活随笔 收集整理的這篇文章主要介紹了 【转】hex和bin文件格式的区别 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

hex和bin文件格式的區別

  Intel HEX文件是記錄文本行的ASCII文本文件,在Intel HEX文件中,每一行是一個HEX記錄,由十六進制數組成的機器碼或者數據常量。Intel HEX文件經常被用于將程序或數據傳輸存儲到ROM、EPROM,大多數編程器和模擬器使用Intel HEX文件。

  很多編譯器的支持生成HEX格式的燒錄文件,尤其是Keil c。但是編程器能夠下載的往往是BIN格式,因此HEX轉BIN是每個編程器都必須支持的功能。HEX格式文件以行為單位,每行由“:”(0x3a)開始,以回車鍵結束(0x0d,0x0a)。行內的數據都是由兩個字符表示一個16進制字節,比如”01”就表示數0x01;”0a”,就表示0x0a。對于16位的地址,則高位在前低位在后,比如地址0x010a,在HEX格式文件中就表示為字符串”010a”。

  下面為HEX文件中的一行:

  :10000000FF0462FF051EFF0A93FF0572FF0A93FFBC

   “:”表示一行的開始。 “:”后的第1,2個字符“10”表示本行包含的數據的長度,這里就是0x10即16個。 第3,4,5,6個字符“0000”表示數據存儲的起始地址,這里表示從0x0000地址開始存儲16個數據,其中高位地址在前,低位地址在后。 第7,8個字符“00”表示數據的類型。該類型總共有以下幾種: 00 ----數據記錄 01 ----文件結束記錄 02 ----擴展段地址記錄 04 ----擴展線性地址記錄

  這里就是0x00即為普通數據記錄。自后的32個字符就是本行包含的數據,每兩個字符表示一個字節數據,總共有16個字節數據跟行首的記錄的長度相一致。最后兩個字符表示校驗碼。每個HEX格式的最后一行都是固定為:

:00000001FF

  以上的信息其實就足夠進行HEX轉BIN格式的程序的編寫。首先我們只處理數據類型為0x00及0x01的情況。0x02表示對應的存儲地址超過了64K,由于我的編程器只針對64K以下的單片機,因此在次不處理,0x04也是如此。

?

?

記錄格式

一個Intel HEX文件可以包含任意多的十六進制記錄,每條記錄有五個域,下面是一個記錄的格式:

:llaaaatt[dd...]cc

每一組字母是獨立的一域,每一個字母是一個十六進制數字,每一域至少由兩個十六進制數字組成,下面是字節的描述.

:冒號 是每一條Intel HEX記錄的開始

ll 是這條記錄的長度域,他表示數據(dd)的字節數目。

aaaa 是地址域,他表示數據的起始地址<如果是數據記錄,這表示將要燒錄的這條記錄中的數據在EPROM中的偏移地址,對于不支持擴展段地址和擴展線性地址的,如89C51,這就是此條記錄的起始地址>

tt 這個域表示這條HEX記錄的類型,他有可能是下面這幾種類型 00 ----數據記錄 01 ----文件結束記錄 02 ----擴展段地址記錄 04 ----擴展線性地址記錄

dd 是數據域,表示一個字節的數據,一個記錄可能有多個數據字節,字節數目可以查看ll域的說明

cc 是效驗和域,表示記錄的效驗和,計算方法是將本條記錄冒號開始的所有字母對<不包括本效驗字和冒號> 所表示的十六進制數字<一對字母表示一個十六進制數,這樣的一個十六進制數為一個字節>都加起來然后模除256得到的余數,最后求出余數的補碼,即是本效驗字節cc。

<例如: :0300000002005E9D cc=0x01+NOT((0x03+0x00+0x00+0x00+0x02+0x00+0x5E)%0x100)=0x01+0x9C=0x9D

C語言描述: UCHAR cc; cc=(UCHAR)~(0x03+0x00+0x00+0x00+0x02+0x00+0x5E); cc++; >

?

數據記錄

Intel HEX文件由若干個數據記錄組成,一個數據記錄以一個回車和一個換行結束<回車為0x0d換行為0x0a> 比如下面的一條數據記錄 :10246200464C5549442050524F46494C4500464C33 10  是此行記錄數據的字節數目 2462 ?是數據在內存<將要燒寫的eprom地址>中的起始地址 00   ?是記錄類型00(是一個數據記錄) 464C ?到 464C 是數據 33 ? ? ?是此行記錄的效驗和

?

擴展線性地址記錄(HEX386) 擴展線性地址記錄也可稱為32位地址記錄/HEX386記錄,這個紀錄包含高16(16-31位)位數據地址,這種擴展的線性記錄總是有兩個字節數據,像下面這樣: :02000004FFFFFC 02 是記錄的數據字節數目 0000 是地址域,這在擴展地址記錄中總是0000 04 是記錄類型04(擴展地址記錄) FFFF 是高16位地址 FC 是記錄效驗和,計算方法如下: 01h + NOT(02h + 00h + 00h + 04h + FFh + FFh) 當一個擴展線性地址記錄被讀到后,擴展線性地址記錄的數據區域將被保存,并應用到后面從Intel HEX文件中讀出的記錄,這個擴展線性記錄一直有效,直到讀到下一個擴展線性記錄。 絕對內存地址 = 數據記錄中的地址 + 移位后的擴展線性地址 下面舉例說明這個過程:從數據記錄的地址域得到地址 2462,從擴展線性地址記錄的地址域得到地址 FFFF,絕對內存地址 FFFF2462

?

擴展段地址記錄 (HEX86)

擴展段地址記錄也被稱為HEX86記錄,包含 4-19位的數據地址段,這個擴展段地址記錄總是有兩字節數據,如下: :020000021200EA 02 是 記錄中的數據字節數目 0000 是地址域,在擴展段地址記錄中,這個域總是0000 02 是記錄類型,02(擴展段地址的標示) 1200 是該段的地址 EA 是效驗和 計算如下: 01h + NOT(02h + 00h + 00h + 02h + 12h + 00h). 當擴展段地址記錄被讀后,擴展段地址將被存儲并應用到以后從Intel HEX文件讀出的記錄,這個段地址一直有效直到讀到下一個擴展段地址記錄 絕對內存地址 = 數據記錄中的地址 + 移位后的擴展段地址 數據記錄中的地址域,移位后擴展段地址記錄中的地址域。 下面舉例說明這個過程:從數據記錄的地址域得到地址 2 4 6 2,從擴展段地址記錄的地址域得到地址 1 2 0 0,絕對內存地址 0 0 0 1 4 4 6 2

?

文件結束記錄(EOF) 一個Intel HEX文件必須有一個文件結束記錄,這個記錄的類型域必須是01, 一個EOF記錄總是這樣: :00000001FF 00是記錄中數據字節的數目 0000這個地址對于EOF記錄來說無任何意義 01記錄類型是01(文件結束記錄標示) FF是效驗和計算如下:01h + NOT(00h + 00h + 00h + 01h).

?

格式:BBAAAATTHHHH...HHHHCC

BB: Byte AAAA:數據記錄的開始地址,高位在前,地位在后。因為這個格式只支持8bits,地址被倍乘。所以,為了得到實際的PIC的地址,需要將地址除以2 TT: Type 00 數據記錄 01 記錄結束 04 擴展地址記錄(表示32位地址的前綴,當然這種只能在 INHX32) HHHH:一個字(Word)的數據記錄,高Byte在前,低Byte在后。TT之后,總共有 BB/2 個字 的數據 CC: 一個Byte的CheckSum

因為PIC16F873A只有4K的程序空間,所以,不會有 TT=04的 Linear Address Record?

  hex和bin文件格式   Hex文件,這里指的是Intel標準的十六進制文件,也就是機器代碼的十六進制形式,并且是用一定文件格式的ASCII碼來表示。具體格式介紹如下: Intel hex 文件常用來保存單片機或其他處理器的目標程序代碼。它保存物理程序存儲區中的目標代碼映象。一般的編程器都支持這種格式。?

Intel hex 文件全部由可打印的ASCII字符組成,如下例所示:

:2000000012014c75a800e4f508f509780a7a78e4f608dafcd283fcfded240af9a7050dbd81 :2000200000010ced2488ec34ff50edc283e4fcfded240af9e76d7013ed33e43c700d0dbd2a :2000400000010ced2488ec34ff50e50509e50970020508e50924a8e50834fd50aee4f50874

Intel hex 由一條或多條記錄組成,每條記錄都由一個冒號“:”打頭,其格式如下:

:CCAAAARR...ZZ

其中: CC   ?本條記錄中的數據字節數

AAAA  本條記錄中的數據在存儲區中的起始地址

RR    記錄類型:     00 數據記錄 (data record)     01 結束記錄 (end record)     02 段記錄 (paragraph record)     03 轉移地址記錄 (transfer address record)

...     數據域

ZZ    數據域校驗和

校驗值:每一行的最后一個值為此行數據的校驗和。例如:

:1000000018F09FE518F09FE518F09FE518F09FE5C0 這行中的 0xC0

:1000100018F09FE5805F20B9F0FF1FE518F09FE51D 這行中的 0x1D

校驗和的算法為:計算從0x3A 以后(不包括0x3A)的所有各字節的和模256的余。即各字節二進制算術和,不計超過256的溢出值,然后用0x100減去這個算數累加和,得出得值就是此行得校驗和。

  Intel hex文件記錄中的數字都是16進制格式,兩個16進制數字代表一個字節。CC域是數據域中的實際字節數,地址、記錄類型和校驗和域沒有計算在內。校驗和是取記錄中從數據字節計數域(CC)到數據域(...)最后一個字節的所有字節總和的2的補碼。

  而Bin文件是最純粹的二進制機器代碼,沒有格式,或者說是"順序格式"。按assembly code順序翻譯成binary machine code。由于分析出來Hex文件中的數據域ASCII碼表示的十六進制與二進制一一對應,而且我公司DSP又是16位的,以一個word為最小單位,所以四個十六進制ASCII碼代表一條機器指令單位或者地址,借于上面分析,編寫了工具代碼。大體原理是用fscanf函數在每行的數據域讀入四個ASCII碼,以短整形(short int 16bit)形式儲存,在把這個短整形變量順序fwrite到文件流中去即可。

舉一例說明: 表1

ORG 0000H LJMP START ORG 040H START: MOV SP, #5FH  ;設堆棧 LOOP: NOP LJMP LOOP    ;循環 END        ;結束 ?

表2?

:03000000020040BB :0700400075815F000200431F

表3         

02 00 40 FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF 75 81 5F 00 02 00 43 ?

  表1為源程序,表2是匯編后得到的HEX文件,表3是由HEX文件轉換成的目標文件,也就是最終寫入EPROM的文件,它由編程器轉換得到,也可以由 HEXBIN一類的程序轉換得到。學過手工匯編者應當不難找出表3與表1的一一對應關系,值得注意的是從02 00 40后開始的一長串‘FF’,直到75 81,這是由于偽指令:ORG 040H造成的結果。

/* 使用方法 : bin2hex -b adress filename -b : 指示hex文件起始地址 address : hex文件的起始地址(FIXME:當前版本只支持k字節邊界) filename: 待轉換的文件名 示例 : bin2hex -b 32k rom.bin */#include <stdio.h> #include <stdlib.h> #include <string.h> FILE *fp_read; /* 待讀取文件句柄 */ FILE *fp_write; /* 待寫入文件句柄 */ unsigned long start_adr; /* 轉換成Hex格式的起始地址 */ unsigned short cur_base; /* 轉換成Hex格式的當前地址高16位 */ unsigned short cur_offset; /* 轉換成Hex格式的當前地址低16位 */ unsigned char read_buf[16]; unsigned char write_buf[48]; void calc_start_adr (char *buf) { unsigned int len; len = strlen(buf); if ((buf[len-1] != 'k') && (buf[len-1] != 'K')) { printf ("Invalid argument.\n"); exit (-1); } buf[len-1] = 0; start_adr = atoi (buf); start_adr = start_adr * 1024; cur_base = start_adr >> 16; cur_offset = (unsigned short)start_adr; } void start_convert (void) { unsigned char cnt; unsigned char read_num; unsigned char cksum, highc, lowc; /* 設置當前地址高16位 */ highc = cur_base >> 8; lowc = (unsigned char)cur_base; cksum = 2 + 4 + highc + lowc; cksum = 0xFF - cksum; cksum = cksum + 1; sprintf (write_buf, ":02000004%04x%02x", cur_base, cksum); write_buf[15] = 0x0D; write_buf[16] = 0x0A; fwrite (write_buf, 1, 17, fp_write); read_num = fread (read_buf, 1, 16, fp_read); while (read_num == 16) { /* 寫入讀取的16字節 */ highc = cur_offset >> 8; lowc = (unsigned char)cur_offset; cksum = 0x10 + highc + lowc;      for (cnt=0; cnt<16; cnt++) { cksum += read_buf[cnt]; } cksum = 0xFF - cksum; cksum = cksum + 1; sprintf ( write_buf, ":10%02x%02x00%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x",       highc, lowc,       read_buf[0], read_buf[1], read_buf[2], read_buf[3],       read_buf[4], read_buf[5], read_buf[6], read_buf[7],       read_buf[8], read_buf[9], read_buf[10], read_buf[11],       read_buf[12], read_buf[13], read_buf[14], read_buf[15],       cksum); write_buf[43] = 0x0D; write_buf[44] = 0x0A; fwrite (write_buf, 1, 45, fp_write); /* 計算當前地址低16位,當越限時寫入當前地址高16位 */ if (cur_offset == 65520) { cur_offset = 0; cur_base ++; highc = cur_base >> 8; lowc = (unsigned char)cur_base; cksum = 2 + 4 + highc + lowc; cksum = 0xFF - cksum; cksum = cksum + 1; sprintf (write_buf, ":02000004%04x%02x", cur_base, cksum); write_buf[15] = 0x0D; write_buf[16] = 0x0A; fwrite (write_buf, 1, 17, fp_write); } else { cur_offset += 16; } read_num = fread (read_buf,1,16,fp_read); } /* 寫入剩余的字節 */ if (read_num) { highc = cur_offset >> 8; lowc = (unsigned char)cur_offset; cksum = read_num + highc + lowc; for (cnt=0; cnt<read_num; cnt++) { cksum += read_buf[cnt]; } cksum = 0xFF - cksum; cksum = cksum + 1; sprintf (write_buf, ":%02x%02x%02x00", read_num, highc, lowc); for (cnt=0; cnt<read_num; cnt++) { sprintf (&write_buf[9 + cnt * 2], "%02x", read_buf[cnt]); } sprintf (&write_buf[9 + cnt * 2], "%02x", cksum); write_buf[11 + read_num *

轉載于:https://www.cnblogs.com/skullboyer/p/7978189.html

總結

以上是生活随笔為你收集整理的【转】hex和bin文件格式的区别的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。

主站蜘蛛池模板: 毛片毛片毛片毛片毛片毛片毛片毛片毛片毛片 | 免费在线网站 | 精品无码久久久久国产 | 欧美aa大片| 性一交一乱一区二区洋洋av | 国产九九在线 | 亚洲中文字幕无码一区 | 国产三级午夜理伦三级 | 美国黄色a级片 | 欧美乱大交xxxxx潮喷l头像 | 三级欧美视频 | 亚洲在线观看av | 91精品一区二区三区综合在线爱 | 欧美熟妇毛茸茸 | 国产精欧美一区二区三区白种人 | 青青青在线免费观看 | 国产熟妇一区二区三区四区 | 色图在线观看 | 亚洲欧美日韩一区 | 韩国伦理大片 | 红桃视频成人在线 | 午夜九九九 | 丰满人妻一区二区三区46 | 国产伦乱视频 | 日韩在线视频在线观看 | 亚洲网站免费观看 | www 在线观看视频 | 91久久综合亚洲鲁鲁五月天 | 女警白嫩翘臀呻吟迎合 | 岛国免费视频 | 国产精品va无码一区二区 | 亚洲视频在线观看网站 | 欧美视频免费在线 | 亚洲激情图 | 美女又爽又黄免费视频 | 欧美性插动态图 | 亚洲污片| www.欧美.com| 午夜爱爱影院 | 成人性生活免费看 | 99riAv国产精品无码鲁大师 | 破处视频在线观看 | 999精彩视频| 欧美一卡二卡三卡四卡 | 日韩成人精品一区二区三区 | av日韩不卡 | www.黄色一片 | av老司机在线观看 | 国产乱子伦精品无码专区 | 国产1区2区3区 | 木下凛凛子av一区二区三区 | 亚洲四区 | 日本久久99 | 色综合av| 日本在线h | 国产乱轮视频 | 浪潮av网站 | av解说在线观看 | 成人国产精品免费 | 人人爽人人爽人人 | 91n视频| 国产夜夜操 | 国产欧美久久久精品免费 | 亚洲一区中文字幕永久在线 | 青草视频网 | 探花系列在线观看 | 午夜精品福利一区二区蜜股av | 婷婷色基地| 亚洲精品第五页 | 成人tv| 国产精品后入内射日本在线观看 | 久久精品天天中文字幕人妻 | 99天堂网 | 欧美日本免费 | 日本少妇喷水 | 成人精品水蜜桃 | 麻豆91在线| 农村脱精光一级 | 欧美一二级 | www.爆操| 亚洲黄色在线视频 | 一级黄色片免费播放 | 国产经典久久久 | 国产免费无遮挡 | 三级全黄做爰龚玥菲在线 | 人妻无码中文久久久久专区 | 啪视频网站 | 欧美肥妇bwbwbwbxx | 中文字幕亚洲欧美 | 久久久国产一区二区三区 | 免费看的黄色录像 | 亚洲激情在线播放 | 在线欧美亚洲 | 噜噜噜噜私人影院 | 黄色成人一级片 | 艳情五月| 99免费 | 欧美日韩激情在线 | 自拍偷拍免费 |