计算机系统基础日志No.5

    xiaoxiao2025-01-21  7

    计算机系统基础日志No.4 show bytes-打印数据的字节表示形式

    文章目录

    一,原程序及编译运行1.源程序2.编译运行 二,程序拓展1.把byte_pointer改为int *1>程序结果2>int*结果分析 2.把byte_pointer改为char *1>程序结果2>char*结果分析

    一,原程序及编译运行

    1.源程序

    /* show-bytes - prints byte representation of data */ /* $begin show-bytes */ #include <stdio.h> /* $end show-bytes */ #include <stdlib.h> #include <string.h> /* $begin show-bytes */ typedef unsigned char *byte_pointer; //typedef char *byte_pointer; //typedef int *byte_pointer; void show_bytes(byte_pointer start, size_t len) { size_t i; for (i = 0; i < len; i++) printf("%p\t0x%.2x\n", &start[i], start[i]); printf("\n"); } void show_int(int x) { show_bytes((byte_pointer) &x, sizeof(int)); } void show_float(float x) { show_bytes((byte_pointer) &x, sizeof(float)); } void show_pointer(void *x) { show_bytes((byte_pointer) &x, sizeof(void *)); } /* $end show-bytes */ /* $begin test-show-bytes */ void test_show_bytes(int val) { int ival = val; //float fval = (float) ival; double fval = (double) ival; int *pval = &ival; printf("Stack variable ival = %d\n", ival); printf("(int)ival:\n"); show_int(ival); printf("(float)ival:\n"); show_float(fval); printf("&ival:\n"); show_pointer(pval); } /* $end test-show-bytes */ void simple_show_a() { /* $begin simple-show-a */ int val = 0x87654321; byte_pointer valp = (byte_pointer) &val; show_bytes(valp, 1); /* A. */ show_bytes(valp, 2); /* B. */ show_bytes(valp, 3); /* C. */ /* $end simple-show-a */ } void simple_show_b() { /* $begin simple-show-b */ int val = 0x12345678; byte_pointer valp = (byte_pointer) &val; show_bytes(valp, 1); /* A. */ show_bytes(valp, 2); /* B. */ show_bytes(valp, 3); /* C. */ /* $end simple-show-b */ } void float_eg() { int x = 3490593; float f = (float) x; printf("For x = %d\n", x); show_int(x); show_float(f); x = 3510593; f = (float) x; printf("For x = %d\n", x); show_int(x); show_float(f); } void string_ueg() { /* $begin show-ustring */ const char *s = "ABCDEF"; show_bytes((byte_pointer) s, strlen(s)); /* $end show-ustring */ } void string_leg() { /* $begin show-lstring */ const char *s = "abcdef"; show_bytes((byte_pointer) s, strlen(s)); /* $end show-lstring */ } void show_twocomp() { /* $begin show-twocomp */ short x = 12345; short mx = -x; show_bytes((byte_pointer) &x, sizeof(short)); show_bytes((byte_pointer) &mx, sizeof(short)); /* $end show-twocomp */ } int main(int argc, char *argv[]) { int val = 12345; if (argc > 1) { val = strtol(argv[1], NULL, 0); printf("calling test_show_bytes\n"); test_show_bytes(val); } else { printf("calling show_twocomp\n"); show_twocomp(); printf("Calling simple_show_a\n"); simple_show_a(); printf("Calling simple_show_b\n"); simple_show_b(); printf("Calling float_eg\n"); float_eg(); printf("Calling string_ueg\n"); string_ueg(); printf("Calling string_leg\n"); string_leg(); } return 0; }

    2.编译运行

    calling show_twocomp 0x7fffc3b39ee4 0x39 0x7fffc3b39ee5 0x30 0x7fffc3b39ee6 0xc7 0x7fffc3b39ee7 0xcf Calling simple_show_a 0x7fffc3b39edc 0x21 0x7fffc3b39edc 0x21 0x7fffc3b39edd 0x43 0x7fffc3b39edc 0x21 0x7fffc3b39edd 0x43 0x7fffc3b39ede 0x65 Calling simple_show_b 0x7fffc3b39edc 0x78 0x7fffc3b39edc 0x78 0x7fffc3b39edd 0x56 0x7fffc3b39edc 0x78 0x7fffc3b39edd 0x56 0x7fffc3b39ede 0x34 Calling float_eg For x = 3490593 0x7fffc3b39ebc 0x21 0x7fffc3b39ebd 0x43 0x7fffc3b39ebe 0x35 0x7fffc3b39ebf 0x00 0x7fffc3b39ebc 0x84 0x7fffc3b39ebd 0x0c 0x7fffc3b39ebe 0x55 0x7fffc3b39ebf 0x4a For x = 3510593 0x7fffc3b39ebc 0x41 0x7fffc3b39ebd 0x91 0x7fffc3b39ebe 0x35 0x7fffc3b39ebf 0x00 0x7fffc3b39ebc 0x04 0x7fffc3b39ebd 0x45 0x7fffc3b39ebe 0x56 0x7fffc3b39ebf 0x4a Calling string_ueg 0x5557af22ad34 0x41 0x5557af22ad35 0x42 0x5557af22ad36 0x43 0x5557af22ad37 0x44 0x5557af22ad38 0x45 0x5557af22ad39 0x46 Calling string_leg 0x5557af22ad3b 0x61 0x5557af22ad3c 0x62 0x5557af22ad3d 0x63 0x5557af22ad3e 0x64 0x5557af22ad3f 0x65 0x5557af22ad40 0x66

    二,程序拓展

    1.把byte_pointer改为int *

    1>程序结果

    calling show_twocomp 0x7ffe0e250ef4 0xcfc73039 0x7ffe0e250ef8 0x1549db00 0x7ffe0e250ef6 0xdb00cfc7 0x7ffe0e250efa 0xda411549 Calling simple_show_a 0x7ffe0e250eec 0x87654321 0x7ffe0e250eec 0x87654321 0x7ffe0e250ef0 0xe250eec 0x7ffe0e250eec 0x87654321 0x7ffe0e250ef0 0xe250eec 0x7ffe0e250ef4 0x7ffe Calling simple_show_b 0x7ffe0e250eec 0x12345678 0x7ffe0e250eec 0x12345678 0x7ffe0e250ef0 0xe250eec 0x7ffe0e250eec 0x12345678 0x7ffe0e250ef0 0xe250eec 0x7ffe0e250ef4 0x7ffe Calling float_eg For x = 3490593 0x7ffe0e250ecc 0x354321 0x7ffe0e250ed0 0xe250f00 0x7ffe0e250ed4 0x7ffe 0x7ffe0e250ed8 0xbbe37a6c 0x7ffe0e250ecc 0x4a550c84 0x7ffe0e250ed0 0xe250f00 0x7ffe0e250ed4 0x7ffe 0x7ffe0e250ed8 0xbbe37a7c For x = 3510593 0x7ffe0e250ecc 0x359141 0x7ffe0e250ed0 0xe250f00 0x7ffe0e250ed4 0x7ffe 0x7ffe0e250ed8 0xbbe37aad 0x7ffe0e250ecc 0x4a564504 0x7ffe0e250ed0 0xe250f00 0x7ffe0e250ed4 0x7ffe 0x7ffe0e250ed8 0xbbe37abd Calling string_ueg 0x5602bbe37d44 0x44434241 0x5602bbe37d48 0x61004645 0x5602bbe37d4c 0x65646362 0x5602bbe37d50 0x61630066 0x5602bbe37d54 0x6e696c6c 0x5602bbe37d58 0x65742067 Calling string_leg 0x5602bbe37d4b 0x64636261 0x5602bbe37d4f 0x63006665 0x5602bbe37d53 0x696c6c61 0x5602bbe37d57 0x7420676e 0x5602bbe37d5b 0x5f747365 0x5602bbe37d5f 0x776f6873

    2>int*结果分析

    为什么会是这个呢? 通过debug,发现 printf("%.2x", start[i]); start[i]被解释为了int。所以,程序每次读取4个字节(int 的大小),并以16进制输出。 可以通过内存值来证明 start[0] 39 30 00 00 -> 3039 start[1] 5a 10 3a 01 -> 013a 105a start[2] 5a 10 3a 01 -> 013a 105a start[3] 00 90 f0 00 -> 00f0 0900 这也和输出是符合的。

    2.把byte_pointer改为char *

    1>程序结果

    calling show_twocomp 0x7ffdc1d86654 0x39 0x7ffdc1d86655 0x30 0x7ffdc1d86656 0xffffffc7 0x7ffdc1d86657 0xffffffcf Calling simple_show_a 0x7ffdc1d8664c 0x21 0x7ffdc1d8664c 0x21 0x7ffdc1d8664d 0x43 0x7ffdc1d8664c 0x21 0x7ffdc1d8664d 0x43 0x7ffdc1d8664e 0x65 Calling simple_show_b 0x7ffdc1d8664c 0x78 0x7ffdc1d8664c 0x78 0x7ffdc1d8664d 0x56 0x7ffdc1d8664c 0x78 0x7ffdc1d8664d 0x56 0x7ffdc1d8664e 0x34 Calling float_eg For x = 3490593 0x7ffdc1d8662c 0x21 0x7ffdc1d8662d 0x43 0x7ffdc1d8662e 0x35 0x7ffdc1d8662f 0x00 0x7ffdc1d8662c 0xffffff84 0x7ffdc1d8662d 0x0c 0x7ffdc1d8662e 0x55 0x7ffdc1d8662f 0x4a For x = 3510593 0x7ffdc1d8662c 0x41 0x7ffdc1d8662d 0xffffff91 0x7ffdc1d8662e 0x35 0x7ffdc1d8662f 0x00 0x7ffdc1d8662c 0x04 0x7ffdc1d8662d 0x45 0x7ffdc1d8662e 0x56 0x7ffdc1d8662f 0x4a Calling string_ueg 0x55bb9bfdbd34 0x41 0x55bb9bfdbd35 0x42 0x55bb9bfdbd36 0x43 0x55bb9bfdbd37 0x44 0x55bb9bfdbd38 0x45 0x55bb9bfdbd39 0x46 Calling string_leg 0x55bb9bfdbd3b 0x61 0x55bb9bfdbd3c 0x62 0x55bb9bfdbd3d 0x63 0x55bb9bfdbd3e 0x64 0x55bb9bfdbd3f 0x65 0x55bb9bfdbd40 0x66

    2>char*结果分析

    再次debug此时start[i]被解释为了char test =12345的16进制为00003039。 test=54321的16进制为0000d431 而问题就是出现在这。 在打印test的情况下, start[0] 39 <128 start[1] 30 <128 start[2] 00 <128 start[3] 00 <128 都是在char的正常范围。但是在打印test=54321的情况下 start[0] 31 <128 start[1] d4 >128 start[2] 00 <128 start[3] 00 <127 在打印start[1]时,值超过了char的正常范围。本来也是没什么问题的,但是此时打印格式是16进制。所以程序按照补码扩充。 d4 -> 1101 0111 -> 1111 1111 1111 1111 1111 1111 1101 0111->F F F F F F D 4 所以出了错误

    最新回复(0)