当前位置: 首页 > news >正文

《汇编语言:基于X86处理器》第1章 复习题和练习

本篇记录《汇编语言:基于X86处理器》第1章 复习题和练习的学习笔记。

1.7 复习题和练习

1.7.1 简答题

1.在一个8位二进制整数中,哪一位是最高有效位MSB)?

答:最左边的第1位。

2.下列无符号二进制整数的十进制表示分别是什么?

a. 0011 0101

b. 1001 0110

c. 1100 1100

答:a为53,b为150,c为204

3.下列每组二进制整数的和分别是多少?

a. 1010 1111 + 1101 1011

b. 1001 0111 + 1111 1111

c. 0111 0101 + 1010 1100

答:a=0001 1000 1010 = 394,b=0001 1001 0110 = 406,c=0001 0010 0001 = 289

4.计算二进制减法(0000 1101-0000 0111)。

答:0000 0110 = 6

5.下列每种数据类型各包含多少位?

a.字            b.双字                 c.四字

答:a为16位,b为32位,c为64位

6.表示下列无符号十进制整数时,需要的最少二进制位分别是多少?

a.4095           b.65534               c.42319

答:a需要12位, b需要16位,c需要16位

7.下列二进制数的十六进制表示分别是什么?

a. 0011 0101 1101 1010           b. 1100 1110 1010 0011              c. 1111 1110 1101 1011

答:a=35DA,b=CEA3 , c=FEDB

8.下列十六进制数的二进制表示分别是什么?

a. 0126 F9D4          b.6ACD FA95                    c.F69B DC2A

答:a=0001 0010 0110 1111 1001 1101 0100

b=0110 1010 1100 1101 1111 1010 1001 0101

c=1111 0110 1001 1011 1101 1100 0010 1010

9.下列十六进制整数的无符号十进制表示分别是什么?

a. 3A             b. 1BF            c.1001

答:a=58, b=447, c=4097

10.下列十六进制整数的无符号十进制表示分别是什么?

a.62             b.4B3             c. 29F

答:a=98, b=1203, c=671

11.下列有符号十进制整数的16位十六进制表示分别是什么?

a. -24          b. -331

答:a=FFE8, b=FEB5

12.下列有符号十进制整数的16位十六进制表示分别是什么?

a. -21               b. -45

答:a=FFEB, b=FFD3

13.将下列 16 位十六进制有符号整数转换为十进制数。

a. 6BF9              b. C123

答:a=27641, b=-16093

14.将下列 16 位十六进制有符号[[整数转换为十进制数。

a. 4CD2                b. 8230

答:a=19666, b=-32208

15.下列有符号二进制数的十进制表示分别是什么?

a. 1011 0101                  b. 0010 1010                c.11110000

答:a=-75, b=42, c=-16

16.下列有符号二进制数的十进制表示分别是什么?

a.1000 0000              b.1100 1100                 c.1011 0111

答:a=-128, b=-52, c=-73

17.下列有符号十进制整数的8位二进制(补码)表示分别是什么?

a.-5            b.-42               c.-16

答:a=1111 1011, b=1101 0110, c=1111 0000

18.下列有符号十进制整数的8位二进制(补码)表示分别是什么?

a.-72            b.-98                c.-26

答:a=1011 1000, b=1001 1110, c=1110 0110

19.下列每组十六进制整数的和分别是多少?

a.6B4 + 3FE                  b.A49 + 6BD

答:a=AB2, b=1106

20.下列每组十六进制整数的和分别是多少?

a.7C4 + 3BE                b.B69 + 7AD

答:a=B82, b=1316

21.ASCI字符大写“B”的十六进制和十进制表示分别是什么?

答:“B”的十六进制是42,十进制是66

22.ASCII字符大写“G”的十六进制和十进制表示分别是什么?

答:“G”的十六进制是47,十进制是71

23.挑战:129位无符号整数能表示的最大十进制值是多少?

答:10^{129}-1(10的129次方减1)

24.挑战:86位有符号整数能表示的最大十进制值是多少?

答:10^{85}-1(10的85次方减1)

25.构造一个真值表,表示布尔函数~(A^B)所有可能的输人和输出。

答:

X

Y

~(X^Y )

F

F

T

F

T

T

T

F

T

T

T

F

26.构造一个真值表,表示布尔函数(~A^~B)所有可能的输入和输出。说明此表与 25 题真值表中最右列之间的关系。听说过摩根定理吗?

答:

X

Y

~X^~Y

F

F

T

F

T

F

T

F

F

T

T

F

~A∧~B 等价于 ~(A∨B)(NOR运算),这是摩根定理的直接体现。

摩根定理(De Morgan's Laws)

摩根定理是布尔代数中的核心定律,揭示了与/或运算和取反运算之间的关系:

第一定律:

  1. ¬(A∧B)≡¬A∨¬B¬(A∧B)≡¬A∨¬B
    • "与非"等价于"非A 或 非B"

第二定律:

  1. ¬(A∨B)≡¬A∧¬B¬(A∨B)≡¬A∧¬B
    • "或非"等价于"非A 与 非B"(即本题的 ~A ∧ ~B

27.如果一个布尔函数有4个输人,则其真值表需要多少行?

答:16行,如果一个布尔函数有4个输入,其真值表需要16行‌。这是因为每个输入变量都有两种可能的状态(0或1),所以4个输入变量的所有组合共有24=1624=16种。

28.4输入的多路选择器需要多少个选择位?

答: 4输入的多路选择器需要 2个选择位(也称为控制位或地址位)。

1.7.2算法基础

下列编程练习可以选择任何高级编程语言。不要调用已有的库函数来自动完成这些任务。(比如标准C库中的sprinf和sscanf函数。)

1.编写一个函数来接收一个 16 位 二进制整数字符串。函数返回值为该字符串的整数值。

//1.7.2_1.c   1.编写一个函数来接收一个 16 位 二进制整数字符串。函数返回值为该字符串的整数值。#include <stdio.h>short binaryStringToShort(const char* ch)
{int len = strlen(ch);printf("len=======================%d\n", len);//16位的二进制最多16个字符('0'或'1')if (len < 1 || len > 8)return -1;short sum = 0;for (int i = 0; i < len; ++i){char temp = ch[i];if (temp == '0')	//0不用计算continue;if (temp == '1'){sum += (1 << (len - i - 1));   // 二进制位为1时转为十进制 = 2的(n-1)次方}else{return -2; //数据错误}}//printf("sum=======================%hd\n", sum);return sum;
}int main()
{printf("sizeof(short)=============%d\n", sizeof(short));//char str[9] = { "10010101" };//str[8] = '\0';char str[] = {'1','0','0','1','0','1','0','1','\0'};  // 1001 0101short ret = binaryStringToShort(str);printf("%s=======================%d\n", str, ret);printf("hello world\n");return 0;
}

运行结果:

2.编写一个函数来接收一个 32 位 十六进制整数字符串。函数返回值为该字符串的整数值。

//1.7.2_2.c   2.编写一个函数来接收一个 32 位 十六进制整数字符串。函数返回值为该字符串的整数值。#include <stdio.h>int hexadecimalStringToInt(const char* ch)
{int len = strlen(ch);printf("len=======================%d\n", len);//32位的十六进制最多8个字符('0'-'F')if (len < 1 || len > 8)return -1;int sum = 0;for (int i = 0; i < len; ++i){char temp = ch[i];if (temp == '0')	//0不用计算continue;//先转成10进制整数int t = 0;if (temp > '0' && temp <= '9')   //'0'-'9'  ===> 48 - 57{t = temp - 48;}else if (temp >= 'A' && temp <= 'F')   //'A'-'Z'  ===> 65 - 90{t = temp - 55;}else if (temp >= 'a' && temp <= 'f')   //'a'-'z'  ===> 97 - 122{t = temp - 87;}else{return -2; //数据错误}int leftmove = (len - i - 1) * 4;sum += t*(1 << leftmove);   //十六进制位转为十进制 = 16的(n-1)次方   //乘4表示16进制移动一位相当于2进制移动4位,即2的4次方	}return sum;
}int main()
{char str[] = { '1','A','1','2','F','\0' };  // 0001 A12F = 106799//char str[] = { '2','C', '1','F','\0' };  // 2C1F  = 11295//char str[] = { '1','F','\0' };  // 001F   = 31int ret = hexadecimalStringToInt(str);printf("%s=======================%d\n", str, ret);printf("hello world\n");return 0;
}

运行结果:

3.编写一个函数来接收一个整数。函数返回值必须是包含该整数二进制表示的字符串。

//1.7.2_3.c   3.编写一个函数来接收一个整数。函数返回值必须是包含该整数二进制表示的字符串。#include <stdio.h>
#include <string.h>
#include <stdlib.h>#pragma warning(disable: 4996)char* intToBinaryString(int a)
{if (a == 0)return NULL;char temp[33] = { '\0' };int i = 0;int a1 = a;while (a1){temp[i] = a1 % 2 + 48; //整数0或1转成字符‘0’或‘1’++i;a1 = a1 / 2;}int len = i;strrev(temp);  //调整顺序char* retChar = (char*)malloc(len + 1);strcpy(retChar, temp);retChar[len] = '\0';return retChar;
}int main()
{int a = 149;  // 149 = 1001 0101 char* str = intToBinaryString(a);printf("%d=======================%s\n", a, str);int a2 = 167;  // 167 = 10100111 char* str2 = intToBinaryString(a2);printf("%d=======================%s\n", a2, str2);printf("hello world\n");return 0;
}

运行结果:

 

4.编写一个函数来接收一个整数。函数返回值必须是包含该整数十六进制表示的字符串。

//1.7.2_4.c   4.编写一个函数来接收一个整数。函数返回值必须是包含该整数十六进制表示的字符串。#include <stdio.h>
#include <string.h>
#include <stdlib.h>#pragma warning(disable: 4996)char* intToHexadecimalString(int a)
{if (a == 0)return NULL;char temp[9] = { '\0' };int i = 0;int a1 = a;while (a1){int remainder = a1 % 16; //余数//余数转字符if (remainder >= 0 && remainder <= 9){temp[i] = remainder + 48;		//'0' - '9'}else if (remainder > 9 && remainder < 16){temp[i] = remainder + 55;		//'A' - 'F'}++i;a1 = a1 / 16;}int len = i;strrev(temp);  //调整顺序char* retChar = (char*)malloc(len + 1);strcpy(retChar, temp);retChar[len] = '\0';return retChar;
}int main()
{int a = 856745;  // 856745 = D12A9char* str = intToHexadecimalString(a);printf("%d\t=======================%s\n", a, str);int a2 = 42857;  // 42857 = A769char* str2 = intToHexadecimalString(a2);printf("%d\t=======================%s\n", a2, str2);printf("hello world\n");return 0;
}

5.编写一个函数实现两个以b为基数的数字串相加,其中2<b<10。每个字符串可包含多达1000个数字。函数返回和数,其形式为基数相同的字符串。

运行结果:

6. 编写一个函数实现两个十六进制字符串相加,每个字符串含1000 个数字。函数返回一个十六进制字符串来表示输入之和。

//1.7.2_6.c   #include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <assert.h>#pragma warning(disable: 4996)char intToChar(int a)
{switch (a) {case 0:return '0';case 1:return '1';case 2:return '2';case 3:return '3';case 4:return '4';case 5:return '5';case 6:return '6';case 7:return '7';case 8:return '8';case 9:return '9';case 10:return 'A';case 11:return 'B';case 12:return 'C';case 13:return 'D';case 14:return 'E';case 15:return 'F';default:return '\0';}
}int charToInt(char c)
{switch (c) {case '0':return 0;case '1':return 1;case '2':return 2;case '3':return 3;case '4':return 4;case '5':return 5;case '6':return 6;case '7':return 7;case '8':return 8;case '9':return 9;case 'A':return 10;case 'B':return 11;case 'C':return 12;case 'D':return 13;case 'E':return 14;case 'F':return 15;default:return 0;}
}char* hexadecimalStringAdd(const char* strA, const char* strB)
{int lenA = strlen(strA);int lenB = strlen(strB);if (lenA < 1 || lenB < 1)return NULL;int flag = 0; //进位标志int max = lenA > lenB ? lenA : lenB; //取最长的数字串char temp[1002] = { '\0' };for (int i = 0; i < max; i++){//从最低位开始逐个相加int lastA = lenA - i - 1;int lastB = lenB - i - 1;int a = 0;int b = 0;if (lastA >= 0 && lastA < lenA){a = charToInt(strA[lastA]);			//转为10进制整数}if (lastB >= 0 && lastB < lenB){b = charToInt(strB[lastB]);			//转为10进制整数}int sum = a + b + flag;					//加上进位标志  flag只能是0或1flag = sum / 16;						//两数相加是否有进位int remainder = sum % 16;				//余数temp[i] = intToChar(remainder);			//转为数值型字符}strrev(temp);				//调整顺序int len = strlen(temp);char* retChar = (char*)malloc(len + 1);assert(retChar != NULL);strcpy(retChar, temp);retChar[len] = '\0';return retChar;
}int main()
{char a[7] = { "756745" };a[6] = '\0';char b[4] = { "345" };b[3] = '\0';char* str = hexadecimalStringAdd(a, b);printf("%s + %s\t=======================%s\n", a, b, str);char a2[7] = { "75AC45" };a2[6] = '\0';char b2[6] = { "1A3FC" };b2[5] = '\0';char* str2 = hexadecimalStringAdd(a2, b2);printf("%s + %s\t=======================%s\n", a2, b2, str2);char a3[7] = { "756EB5" };a3[6] = '\0';char b3[8] = { "A4D59CB" };b3[7] = '\0';char* str3 = hexadecimalStringAdd(a3, b3);printf("%s + %s\t=======================%s\n", a3, b3, str3);printf("hello world\n");return 0;
}

运行结果:

7.编写一个函数实现一个长度为1000 位的十六进制数字串与单个位的十六进制数字的乘法。函数返回一个十六进制字符串来表示乘积。

//1.7.2_7.c   #include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <assert.h>
#include <ctype.h>#pragma warning(disable: 4996)char intToChar7(int a)
{switch (a) {case 0:return '0';case 1:return '1';case 2:return '2';case 3:return '3';case 4:return '4';case 5:return '5';case 6:return '6';case 7:return '7';case 8:return '8';case 9:return '9';case 10:return 'A';case 11:return 'B';case 12:return 'C';case 13:return 'D';case 14:return 'E';case 15:return 'F';default:return '\0';}
}int charToInt7(char c)
{switch (c) {case '0':return 0;case '1':return 1;case '2':return 2;case '3':return 3;case '4':return 4;case '5':return 5;case '6':return 6;case '7':return 7;case '8':return 8;case '9':return 9;case 'A':return 10;case 'B':return 11;case 'C':return 12;case 'D':return 13;case 'E':return 14;case 'F':return 15;default:return 0;}
}char* hexadecimalStringMul(const char* str, char hexdigit)
{int len = strlen(str);//char dight = toupper(hexdigit); //小写转大小char dight = hexdigit;if (hexdigit >= 'a' && hexdigit <= 'f')dight = hexdigit - 32; //小写转大小if (len < 1 || (isxdigit(dight) == 0))  //判断是否为16进制数据return NULL;int flag = 0; //进位标志char temp[1002] = { '\0' };//两层循环,内大外小,效率高for (int i = 0; i < len; i++){//从最低位开始逐个相加int lastA = len - i - 1;int a = charToInt7(str[lastA]);			//转为10进制整数int b = charToInt7(dight);				//转为10进制整数int amass = a * b + flag;				//加上进位标志  flag只能是0到15flag = amass / 16;						//两数相加是否有进位int remainder = amass % 16;				//余数temp[i] = intToChar7(remainder);		//转为数值型字符}//最高位可能有进位if (flag > 0)temp[len] = intToChar7(flag);strrev(temp);				//调整顺序int len2 = strlen(temp);char* retChar = (char*)malloc(len2 + 1);assert(retChar != NULL);strcpy(retChar, temp);retChar[len2] = '\0';return retChar;
}int main()
{char a[7] = { "756745" };a[6] = '\0';char b = 'A';char* str = hexadecimalStringMul(a, b);printf("%s * %c\t=======================%s\n", a, b, str);char a2[7] = { "7AC45" };a2[6] = '\0';char b2 = 'B';char* str2 = hexadecimalStringMul(a2, b2);printf("%s * %c\t=======================%s\n", a2, b2, str2);char a3[7] = { "756EB5" };a3[6] = '\0';char b3 = 'E';char* str3 = hexadecimalStringMul(a3, b3);printf("%s * %c\t=======================%s\n", a3, b3, str3);char a4[7] = { "756EB5" };a4[6] = '\0';char b4 = '2';char* str4 = hexadecimalStringMul(a4, b4);printf("%s * %c\t=======================%s\n", a4, b4, str4);printf("hello world\n");return 0;
}

运行结果:

8.编写一个Java 程序实现如下计算,然后用javap-c指令对代码进行反汇编。为每行代码添加注释,以说明该行代码的目的。

int Y;

int X = (Y+4)*3;

解 答:文件名Calculation8.java 这里必须和里面的类名一样,源码如下:

public class Calculation8 {public static void main(String[] args) {int Y = 5;int X = (Y+4)*3;System.out.println(X);}
}

编译测试 

 说明:

Compiled from "Calculation8.java"
public class Calculation8 {public Calculation8();Code:0: aload_0         // 将this引用压入操作数栈1: invokespecial #1 // 调用Object的构造函数: Method java/lang/Object."<init>":()V4: return         // 从构造函数返回public static void main(java.lang.String[]);Code:0: iconst_5       // 将常量5压入操作数栈1: istore_1       // 将栈顶的5存入局部变量表slot 1(Y)2: iload_1        // 从局部变量表slot 1(Y)加载值到栈顶3: iconst_4       // 将常量4压入操作数栈4: iadd           // 弹出栈顶两个值相加(Y+4),结果压回栈顶5: iconst_3       // 将常量3压入操作数栈6: imul           // 弹出栈顶两个值相乘((Y+4)*3),结果压回栈顶7: istore_2       // 将计算结果存入局部变量表slot 2(X)8: getstatic     #2 // 获取System.out静态字段: Field java/lang/System.out:Ljava/io/PrintStream;11: iload_2        // 从局部变量表slot 2(X)加载值到栈顶12: invokevirtual #3 // 调用PrintStream.println方法: Method java/io/PrintStream.println:(I)V15: return         // 从main方法返回
}

9.设计无符号二进制整数减法。用(1000 1000-0000 0101=1000 0011)来检验该方法。再用至少两组其他的整数来检验该方法,每组都是从较大数中减去较小数。

//1.7.2_9.c   #include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <stdbool.h>#pragma warning(disable: 4996)//辅助函数,打印8位二进制数
void printBinary(unsigned char num)
{for (int i = 7; i >= 0; i--){printf("%d", (num >> i) & 1);if (i == 4)printf(" ");	//添加空格便于阅读}
}unsigned char binarySubtract(unsigned char a, unsigned char b, bool *error)
{*error = false;//检查是否a < b(对于无符号数)if (a < b) {*error = true;return 0;}return a - b;
}int main()
{bool error = false;unsigned char result = 0;//测试1unsigned char a = 87;unsigned char b = 63;printBinary(a);printf(" - ");printBinary(b);printf(" = ");result = binarySubtract(a, b, &error);if (error){printf("错误: 被减数小于减数\n");}else{printBinary(result);printf("\n");}//测试2a = 89;b = 75;printBinary(a);printf(" - ");printBinary(b);printf(" = ");result = binarySubtract(a, b, &error);if (error){printf("错误: 被减数小于减数\n");}else{printBinary(result);printf("\n");}//测试3a = 97;b = 15;printBinary(a);printf(" - ");printBinary(b);printf(" = ");result = binarySubtract(a, b, &error);if (error){printf("错误: 被减数小于减数\n");}else{printBinary(result);printf("\n");}//测试4a = 12;b = 75;printBinary(a);printf(" - ");printBinary(b);printf(" = ");result = binarySubtract(a, b, &error);if (error){printf("错误: 被减数小于减数\n");}else{printBinary(result);printf("\n");}printf("hello world\n");return 0;
}

运行结果:

相关文章:

  • C++ 学习 网络编程 2025年6月17日19:56:47
  • Java 时间处理指南:从“踩坑”到“填坑”实战
  • 20倍光学镜头怎么实现20+20倍数实现
  • 基于CNN卷积神经网络识别汉字合集-视频介绍下自取
  • PostgreSQL的扩展lo
  • AI智能体应用市场趋势分析
  • Uniapp性能优化全面指南:从原理到实践
  • 【数据分析三:Data Storage】数据存储
  • C语言——结构体
  • FPGA基础 -- BRAM简介
  • 数据处理考核培训-报表考试要求
  • 利用SMBMAP、SMBCLIENT和NETEXEC进行高效SMB渗透测试
  • 【Akshare】高效下载股票和ETF数据
  • DECOUPLING REPRESENTATION AND CLASSIFIER FOR LONG-TAILED RECOGNITION
  • 远程桌面控制 BilldDesk v0.30.0支持网页版
  • FPGA基础 -- Verilog 门级建模
  • MIT 6.S081 2020 Lab9 File Systems 个人全流程
  • 【Java并发】volatile 与 synchronized 关键字
  • MySQL的事务隔离级别、锁机制、MVCC的原理
  • 【pytest进阶】pytest详解及进阶使用
  • 大厂做网站shijuewang/发布平台有哪些
  • vps云主机可以做网站/推广专家
  • 网站建设内容与实现功能/自己怎么创建网站
  • 南阳网站关键词/网络营销发展现状与趋势
  • 北京网站快速排名优化/交换友情链接推广法
  • 刷网站排名怎么刷/uv推广平台