修改代码如下,然后用命令x /1b 1000 用于dump从内存1000开始的1个字节
#define DUMP_FILE_NAME "d:\\dump.bin"
void bx_dbg_examine_command(char *command, char *format, bx_bool format_passed,
bx_address addr, bx_bool addr_passed)
{
unsigned repeat_count, i;
char ch, display_format, unit_size;
bx_bool iteration, memory_dump = false;
unsigned data_size;
Bit8u data8;
Bit16u data16;
Bit32u data32;
unsigned columns, per_line, offset;
bx_bool is_linear;
unsigned char databuf[8];
dbg_printf("[bochs]:\\n");
::remove(DUMP_FILE_NAME);
// If command was the extended "xp" command, meaning eXamine Physical memory,
// then flag memory address as physical, rather than linear.
if (strcmp(command, "xp") == 0) {
is_linear = 0;
}
else {
is_linear = 1;
}
if (addr_passed==0)
addr = bx_debugger.default_addr;
if (format_passed==0) {
display_format = bx_debugger.default_display_format;
unit_size = bx_debugger.default_unit_size;
repeat_count = 1;
}
else {
if (format==NULL) {
dbg_printf("dbg_examine: format NULL\\n");
bx_dbg_exit(1);
}
if (strlen(format) < 2) {
dbg_printf("dbg_examine: invalid format passed.\\n");
bx_dbg_exit(1);
}
if (format[0] != '/') {
dbg_printf("dbg_examine: '/' is not first char of format.\\n");
bx_dbg_exit(1);
}
format++;
repeat_count = 0;
ch = *format;
iteration = 0;
while ((ch>='0') && (ch<='9')) {
iteration = 1;
repeat_count = 10*repeat_count + (ch-'0');
format++;
ch = *format;
}
if (iteration==0) {
// if no count given, use default
repeat_count = 1;
}
else if (repeat_count==0) {
// count give, but zero is an error
dbg_printf("dbg_examine: repeat count given but is zero.\\n");
return;
}
// set up the default display format and unit size parameters
display_format = bx_debugger.default_display_format;
unit_size = bx_debugger.default_unit_size;
for (i = 0; format [i]; i++) {
switch (ch = format [i]) {
case 'x': // hex
case 'd': // signed decimal
case 'u': // unsigned decimal
case 'o': // octal
case 't': // binary
case 'c': // chars
case 's': // null terminated string
case 'i': // machine instruction
display_format = ch;
break;
case 'b': // bytes
case 'h': // halfwords (two bytes)
case 'w': // words (4 bytes)
case 'g': // giant words (8 bytes)
unit_size = ch;
break;
case 'm': // memory dump
memory_dump = true;
break;
default:
dbg_printf("dbg_examine: invalid format passed. \\'%c\\'\\n", ch);
bx_dbg_exit(1);
break;
}
}
}
if ((display_format == 'i') || (display_format == 's')) {
dbg_printf("error: dbg_examine: 'i' and 's' formats not supported.\\n");
return;
}
if (unit_size == 'g') {
dbg_printf("error: dbg_examine: 'g' (8-byte) unit size not supported.\\n");
return;
}
if (format_passed) {
// store current options as default
bx_debugger.default_display_format = display_format;
bx_debugger.default_unit_size = unit_size;
}
data_size = 0;
per_line = 0;
offset = 0;
if (memory_dump) {
if (display_format == 'c') {
// Display character dump in lines of 64 characters
unit_size = 'b';
data_size = 1;
per_line = 64;
}
else
switch (unit_size) {
case 'b': data_size = 1; per_line = 16; break;
case 'h': data_size = 2; per_line = 8; break;
case 'w': data_size = 4; per_line = 4; break;
//case 'g': data_size = 8; per_line = 2; break;
}
// binary format is quite large
if (display_format == 't')
per_line /= 4;
}
else {
switch (unit_size) {
case 'b': data_size = 1; per_line = 8; break;
case 'h': data_size = 2; per_line = 8; break;
case 'w': data_size = 4; per_line = 4; break;
//case 'g': data_size = 8; per_line = 2; break;
}
}
columns = per_line + 1; // set current number columns past limit
for (i=1; i<=repeat_count; i++) {
if (columns > per_line) {
// if not 1st run, need a newline from last line
if (i!=1)
dbg_printf("\\n");
if (memory_dump)
dbg_printf("0x" FMT_ADDRX ":", addr);
else
dbg_printf("0x" FMT_ADDRX " <bogus+%8u>:", addr, offset);
columns = 1;
}
/* Put a space in the middle of dump, for readability */
if ((columns - 1) == per_line / 2
&& memory_dump && display_format != 'c')
dbg_printf(" ");
if (is_linear) {
if (! bx_dbg_read_linear(dbg_cpu, addr, data_size, databuf)) return;
}
else {
// address is already physical address
BX_MEM(0)->dbg_fetch_mem(BX_CPU(dbg_cpu), (bx_phy_address) addr, data_size, databuf);
}
//FIXME HanishKVC The char display for data to be properly integrated
// so that repeat_count, columns, etc. can be set or used properly.
// Also for data_size of 2 and 4 how to display the individual
// characters i.e in which order to be decided.
switch (data_size) {
case 1:
data8 = databuf[0];
{
FILE* fp = fopen(DUMP_FILE_NAME, "ab+");
if (fp != NULL)
{
fwrite(&data8, 1, 1, fp);
fclose(fp);
}
}
if (memory_dump)
switch (display_format) {
case 'd': dbg_printf("%03d ", data8); break;
case 'u': dbg_printf("%03u ", data8); break;
case 'o': dbg_printf("%03o ", data8); break;
case 't': dbg_printf_binary ("%s ", data8, 8); break;
case 'c': dbg_printf("%c", isprint(data8) ? data8 : '.'); break;
default : dbg_printf("%02X ", data8); break;
}
else
switch (display_format) {
case 'x': dbg_printf("\\t0x%02x", (unsigned) data8); break;
case 'd': dbg_printf("\\t%d", (int) (Bit8s) data8); break;
case 'u': dbg_printf("\\t%u", (unsigned) data8); break;
case 'o': dbg_printf("\\t%o", (unsigned) data8); break;
case 't': dbg_printf_binary("\\t%s", data8, 8); break;
case 'c': bx_print_char(data8); break;
}
break;
case 2:
#ifdef BX_LITTLE_ENDIAN
data16 = * (Bit16u *) databuf;
#else
data16 = (databuf[1]<<8) | databuf[0];
#endif
if (memory_dump)
switch (display_format) {
case 'd': dbg_printf("%05d ", data16); break;
case 'u': dbg_printf("%05u ", data16); break;
case 'o': dbg_printf("%06o ", data16); break;
case 't': dbg_printf_binary ("%s ", data16, 16); break;
default : dbg_printf("%04X ", data16); break;
}
else
switch (display_format) {
case 'x': dbg_printf("\\t0x%04x", (unsigned) data16); break;
case 'd': dbg_printf("\\t%d", (int) (Bit16s) data16); break;
case 'u': dbg_printf("\\t%u", (unsigned) data16); break;
case 'o': dbg_printf("\\t%o", (unsigned) data16); break;
case 't': dbg_printf_binary("\\t%s", data16, 16); break;
case 'c':
bx_print_char(data16>>8);
bx_print_char(data16 & 0xff);
break;
}
break;
case 4:
#ifdef BX_LITTLE_ENDIAN
data32 = * (Bit32u *) databuf;
#else
data32 = (databuf[3]<<24) | (databuf[2]<<16) |
(databuf[1]<<8) | databuf[0];
#endif
if (memory_dump)
switch (display_format) {
case 'd': dbg_printf("%10d ", data32); break;
case 'u': dbg_printf("%10u ", data32); break;
case 'o': dbg_printf("%12o ", data32); break;
case 't': dbg_printf_binary ("%s ", data32, 32); break;
default : dbg_printf("%08X ", data32); break;
}
else
switch (display_format) {
case 'x': dbg_printf("\\t0x%08x", (unsigned) data32); break;
case 'd': dbg_printf("\\t%d", (int) (Bit32s) data32); break;
case 'u': dbg_printf("\\t%u", (unsigned) data32); break;
case 'o': dbg_printf("\\t%o", (unsigned) data32); break;
case 't': dbg_printf_binary("\\t%s", data32, 32); break;
case 'c':
bx_print_char(0xff & (data32>>24));
bx_print_char(0xff & (data32>>16));
bx_print_char(0xff & (data32>> 8));
bx_print_char(0xff & (data32>> 0));
break;
}
break;
}
addr += data_size;
bx_debugger.default_addr = addr;
columns++;
offset += data_size;
}
dbg_printf("\\n");
}