设CS=2500H,DS=2400H,ss==2430H,es=2520H,bp=0200H,si=0010H,di=0206,则add ax,[di+100H]的源操作数的有效地址和物理地址怎么算
时间: 2023-10-20 07:08:25 浏览: 235
首先,根据寻址方式,[di + 100H]表示将寄存器DI的内容加上100H,得到的结果作为偏移地址,加上段寄存器DS的内容,得到的结果作为有效地址。
因此,有效地址 = DS * 10H + DI + 100H = 2400H * 10H + 206H + 100H = 24,706H
接着,根据分段机制,将段寄存器DS左移4位(乘以10H),得到的结果作为段基址,加上偏移地址,得到的结果作为物理地址。
因此,物理地址 = DS * 10H + [di + 100H] = 2400H * 10H + 24,706H = 26,146H
因此,add ax,[di 100H]的源操作数的有效地址为24,706H,物理地址为26,146H。
相关问题
DATAS SEGMENT ;此处输入数据段代码 S DB "ahahk$" T DB "ahk$"; NEXT DB 30 DUP(?) my_no DB 'NOT FOUND',13,10,'$' DATAS ENDS STACKS SEGMENT ;此处输入堆栈段代码 STACKS ENDS CODES SEGMENT ASSUME CS:CODES,DS:DATAS,SS:STACKS START: MOV AX,DATAS MOV ES,AX MOV DS,AX ;此处输入代码段代码 LEA DI,NEXT MOV AX,0 DEC AX STOSB MOV CX,4 MOV BX,AX;BX:K MOV BP,0;BP:J1 L1: CMP BX,0FFFFH;L1 L2 L3 are the first while JE L2 LEA SI,T[(BX)] LODSB MOV DX,AX LEA SI,T[(BP)] LODSB ;MOV DL,T[(BX)] ;MOV AL,T[(BP)] CMP DX,AX JE L2 JNE L3 L2: INC BP INC BX LEA DI,NEXT[(BP)] MOV AX,BX STOSB DEC CX CMP CX,0 JA L1 JNA L14 L3: INC CX LEA SI,NEXT[(BX)] LODSB MOV AH,AL MOV BX,AX DEC CX CMP CX,0 JA L1 JNA L14 L14:MOV BX,0;BX:i MOV BP,0;BP:j L4: MOV CX,0;L4 are the second while MOV DX,2 CMP BX,5 JB L5 L12:CMP BP,3 JB L6 L13:CMP CX,DX JE L7 JNE L8 L5: MOV CX,1 JMP L12 L6: MOV DX,1 JMP L13 L7: CMP BP,0FFFFH JE L9 LEA SI,S[(BX)] LODSB MOV DX,AX LEA SI,T[(BP)] LODSB CMP DX,AX JE L9 JNE L10 L8: CMP BP,3 JNB L11 LEA DX,my_no MOV AH,09H INT 21H MOV AH,4CH INT 21H L9: INC BX INC BP JMP L4 L10:LEA SI,NEXT[(BP)] LODSB MOV AH,AL MOV BP,AX JMP L4 L11:MOV DX,BX SUB DX,3 ADD DX,030H MOV AH,02H INT 21H MOV AH,4CH INT 21H CODES ENDS END START
好的,以下是对给出的代码的注释:
```
DATAS SEGMENT ;定义数据段
S DB "ahahk$" ;定义字符串S,其中包含6个字符:ahahk$
T DB "ahk$"; ;定义字符串T,其中包含4个字符:ahk$
NEXT DB 30 DUP(?) ;定义NEXT数组,包含30个元素,每个元素都是一个字节,初始值为0
my_no DB 'NOT FOUND',13,10,'$' ;定义字符串my_no,其中包含12个字符:NOT FOUND、回车符、换行符和结束符$
DATAS ENDS ;数据段定义结束
STACKS SEGMENT ;定义堆栈段
STACKS ENDS ;堆栈段定义结束
CODES SEGMENT ;定义代码段
ASSUME CS:CODES,DS:DATAS,SS:STACKS ;指定代码段、数据段、堆栈段的段寄存器
START: ;程序入口
MOV AX,DATAS ;将数据段的起始地址赋值给AX寄存器
MOV ES,AX ;将ES寄存器赋值为数据段的起始地址
MOV DS,AX ;将DS寄存器赋值为数据段的起始地址
;以下是代码段的部分
LEA DI,NEXT ;将NEXT数组的地址赋值给DI寄存器
MOV AX,0 ;将AX寄存器赋值为0
DEC AX ;将AX寄存器的值减1(AX=-1)
STOSB ;将AX寄存器中的值存储到DI指向的地址中
MOV CX,4 ;将CX寄存器赋值为4
MOV BX,AX ;将BX寄存器赋值为AX寄存器中的值(BX=-1)
;第一个while循环
L1:
CMP BX,0FFFFH ;比较BX寄存器中的值是否等于0xFFFF(即-1),若等于则跳转到L2
JE L2
LEA SI,T[(BX)] ;将T数组中的第BX个元素的地址赋值给SI寄存器
LODSB ;将SI指向的地址中的值读取到AL寄存器中,并将SI的值加1
MOV DX,AX ;将AX寄存器中的值赋值给DX寄存器
LEA SI,T[(BP)] ;将T数组中的第BP个元素的地址赋值给SI寄存器
LODSB ;将SI指向的地址中的值读取到AL寄存器中,并将SI的值加1
CMP DX,AX ;比较DX寄存器中的值和AX寄存器中的值是否相等
JE L2 ;若相等,则跳转到L2
JNE L3 ;若不相等,则跳转到L3
;L1的下面还有指令,但是这里缺失了,需要补充完整
;第二个while循环
L4:
MOV CX,0 ;将CX寄存器赋值为0
;L4的下面还有指令,但是这里缺失了,需要补充完整
CODES ENDS ;代码段定义结束
END START ;程序结束
```
希望这样的注释能对您有所帮助。
S0 SEGMENT STACK DW 20 DUP(?) TOP LABEL WORD S0 ENDS S1 SEGMENT TIP DB "Please enter ten numbers separated by spaces:", 0DH, 0AH, 24H ARY DW 20 DUP(0) CRLF DB 0DH, 0AH, 24H N DW 0 S1 ENDS S2 SEGMENT ASSUME SS:S0, DS:S1, CS:S2, ES:S1 P PROC FAR MOV AX, S0 MOV SS, AX LEA SP, TOP MOV AX, S1 MOV DS, AX MOV AX, S1 MOV ES, AX LEA DX, TIP MOV AH, 9 INT 21H LEA SI, ARY XOR DX, DX MOV BL, 10 MOV CX, 10 INPUT: MOV AH, 1 INT 21H CMP AL, 20H ;空格分隔字符 JE SAVE;输入十进制数,将数存入SI对应的内存单元 MOV DL, AL MOV AX, [SI] MUL BL SUB DL, 30H ADD AL, DL MOV [SI], AX JMP INPUT SAVE: ADD SI, 2 LOOP INPUT;数组保存完毕 LEA SI, ARY MOV DI, SI ADD DI, 2 ;DI位于数组的第二元素的位置 MOV BP, 9 ;SI移动的次数和每一次比较的次数,第一次为9 GO: MOV CX, BP ;每一次比较的循环次数 MOV BX, [SI] ;第一个数 CMPA: CMP BX, [DI] ;比较后面的数是否比当前的小 JBE CON ;大于就比较下一个 MOV BX, [DI] ;将寄存器中的值替换为最小的值 MOV AX, DI ;AX存放最小值的偏移地址 CON: ADD DI, 2 LOOP CMPA CMP AX, 0 ;如果AX为0,则表示后面的值没有比当前值小 JE NO ;此时SI加一,移动到第二个数 下一次循环比较开始 CHANGE: MOV DX, [SI] ;78-83行替换当前值与最小值 PUSH DX MOV [SI], BX POP DX MOV DI, AX MOV [DI], DX NO: ADD SI, 2 MOV DI, SI ADD DI, 2 CALL PRINT DEC BP ;循环的次数减一 XOR AX, AX ;清除AX的内容,以便76行判断 CMP BP, 1 JNE GO EXIT: MOV AH, 4CH INT 21H P ENDP PRINT PROC NEAR PUSH SI PUSH CX PUSH AX PUSH DX LEA DX, CRLF MOV AH, 9 INT 21H LEA SI, ARY MOV CX, 10 L1: MOV AX, [SI] MOV N, AX CALL OUTPUT ADD SI, 2 MOV DX, 20H MOV AH, 2 INT 21H LOOP L1 POP DX POP AX POP CX POP SI RET PRINT ENDP OUTPUT PROC NEAR PUSH AX PUSH BX PUSH CX PUSH DX XOR CX, CX MOV AX, N MOV BX, 10 L2: XOR DX, DX DIV BX PUSH DX INC CX CMP AX, 0 JNE L2 L3: POP DX ADD DX, 30H MOV AH, 2 INT 21H LOOP L3 POP DX POP CX POP BX POP AX RET OUTPUT ENDP S2 ENDS END 每行是干什么的P
这是一段汇编代码,实现了一个简单的排序程序。下面是各行代码的功能:
第 1 行:定义 S0 段,用于保存堆栈空间。
第 2 行:定义堆栈中的空间大小,20 个字节,每个字节的初始值为问号。
第 3 行:定义 TOP 标号,用于指向堆栈的顶部。
第 4 行:定义 WORD 类型的 TOP 标号。
第 5 行:定义 S0 段的结束。
第 6 行:定义 S1 段,用于保存提示信息和数组变量。
第 7 行:定义 TIP 变量,用于存储提示信息。
第 8 行:定义 ARY 数组变量,用于保存输入的十个数。
第 9 行:定义 CRLF 变量,用于输出换行符。
第 10 行:定义 N 变量,用于保存输入的数。
第 11 行:定义 S1 段的结束。
第 12 行:定义 S2 段,用于保存程序的主体代码。
第 13 行:假设寄存器 SS 指向 S0 段,DS 和 ES 指向 S1 段,CS 指向 S2 段。
第 14 行:定义 PROC 过程,用于执行排序操作。
第 15 行:将 S0 段的地址存入 AX 寄存器中,再将 AX 中的值存入 SS 寄存器中,将堆栈指针 SP 指向 TOP 标号。
第 16 行:将 S1 段的地址存入 AX 寄存器中,再将 AX 中的值存入 DS 和 ES 寄存器中。
第 17 行:将提示信息的地址存入 DX 寄存器中,设置 AH 寄存器的值为 9,调用 DOS 的 21H 中断,显示提示信息。
第 18 行:将 ARY 数组的地址存入 SI 寄存器中,将 DX 和 BX 寄存器清零,将 BP 寄存器的值设置为 9。
第 19 行:定义标号 GO,用于控制循环次数。
第 20 行:将 BP 寄存器的值存入 CX 寄存器中,用于控制每次比较的循环次数。
第 21 行:将 SI 所指向的数值存入 BX 寄存器中,用于比较后面的数是否比当前的小。
第 22 行:定义标号 CMPA,用于比较后面的数是否比当前的小。
第 23 行:将后面的数与当前的数比较,如果大于等于当前的数,则跳转到标号 CON 继续比较下一个数。
第 24 行:将后面的数与当前的数比较,如果小于当前的数,则将最小值保存在 BX 寄存器中,并将 AX 寄存器的值设置为最小值的偏移地址。
第 25 行:将 DI 寄存器的值加 2,指向下一个数。
第 26 行:循环次数减 1。
第 27 行:跳转到标号 CMPA,继续比较下一个数。
第 28 行:如果 AX 的值为 0,则表示后面的值没有比当前值小,跳转到标号 NO。
第 29 行:将 SI 加 2,移动到第二个数,下一次循环比较开始。
第 30 行:定义标号 CHANGE,用于替换当前值和最小值。
第 31 行:将 SI 所指向的数值存入 DX 寄存器中,将当前值替换为最小值,将最小值替换为当前值,将 DI 寄存器的值设置为最小值的偏移地址。
第 32 行:跳转到标号 NO。
第 33 行:将 SI 加 2,移动到下一个数,将 DI 加 2,移动到下一个需要比较的数。
第 34 行:调用 PRINT 过程,输出排序后的数组。
第 35 行:循环次数减 1。
第 36 行:将 AX 寄存器清零,用于判断循环次数是否为 1。
第 37 行:如果循环次数不为 1,则跳转到标号 GO,继续执行排序操作。
第 38 行:定义 EXIT 标号,用于退出程序。
第 39 行:设置 AH 寄存器的值为 4CH,调用 DOS 的 21H 中断,退出程序。
第 40 行:定义 PRINT 过程,用于输出数组。
第 41 行:将 SI 寄存器的值保存到堆栈中,用于后面恢复现场。
第 42 行:将 CX 寄存器的值保存到堆栈中,用于后面恢复现场。
第 43 行:将 AX 寄存器的值保存到堆栈中,用于后面恢复现场。
第 44 行:将 DX 寄存器的值保存到堆栈中,用于后面恢复现场。
第 45 行:将 CRLF 变量的地址存入 DX 寄存器中,设置 AH 寄存器的值为 9,调用 DOS 的 21H 中断,输出换行符。
第 46 行:将 ARY 数组的地址存入 SI 寄存器中,将 CX 寄存器的值设置为 10,用于输出十个数。
第 47 行:定义标号 L1,用于循环输出十个数。
第 48 行:将 SI 所指向的数值存入 AX 寄存器中。
第 49 行:将 AX 寄存器的值存入 N 变量中,用于后面输出十进制数。
第 50 行:调用 OUTPUT 过程,将 N 变量中的数值输出。
第 51 行:将 SI 加 2,移动到下一个数。
第 52 行:将 20H 存入 DX 寄存器中,设置 AH 寄存器的值为 2,调用 DOS 的 21H 中断,输出空格。
第 53 行:循环次数减 1。
第 54 行:如果循环次数不为 0,则跳转到标号 L1,继续输出数组。
第 55 行:从堆栈中恢复 DX 寄存器的值。
第 56 行:从堆栈中恢复 AX 寄存器的值。
第 57 行:从堆栈中恢复 CX 寄存器的值。
第 58 行:从堆栈中恢复 SI 寄存器的值。
第 59 行:返回到调用 PRINT 过程的指令处。
第 60 行:定义 OUTPUT 过程,用于输出十进制数。
第 61 行:将 AX 寄存器的值保存到堆栈中,用于后面恢复现场。
第 62 行:将 BX 寄存器的值保存到堆栈中,用于后面恢复现场。
第 63 行:将 CX 寄存器的值保存到堆栈中,用于后面恢复现场。
第 64 行:将 DX 寄存器的值保存到堆栈中,用于后面恢复现场。
第 65 行:将 CX 寄存器清零,用于计数。
第 66 行:将 N 变量的值存入 AX 寄存器中,将 10 存入 BX 寄存器中,用于进行除法运算。
第 67 行:定义标号 L2,用于进行除法运算。
第 68 行:将 DX 寄存器清零,用于存储余数。
第 69 行:将 AX 寄存器的值除以 BX 寄存器的值,商存入 AX 中,余数存入 DX 中。
第 70 行:将 DX 寄存器的值存入堆栈中,用于后面恢复现场。
第 71 行:将 CX 寄存器的值加 1,用于计数。
第 72 行:将 AX 寄存器的值与 0 进行比较,如果不为 0,则跳转到标号 L2,继续进行除法运算。
第 73 行:定义标号 L3,用于输出十进制数。
第 74 行:从堆栈中恢复 DX 寄存器的值,将其加上 30H,得到字符的 ASCII 码。
第 75 行:将 DX 寄存器的值存入 AH 寄存器中,设置 AH 寄存器的值为 2,调用 DOS 的 21H 中断,输出字符。
第 76 行:循环次数减 1。
第 77 行:如果循环次数不为 0,则跳转到标号 L3,继续输出十进制数。
第 78 行:从堆栈中恢复 DX 寄存器的值。
第 79 行:从堆栈中恢复 CX 寄存器的值。
第 80 行:从堆栈中恢复 BX 寄存器的值。
第 81 行:从堆栈中恢复 AX 寄存器的值。
第 82 行:返回到调用 OUTPUT 过程的指令处。
第 83 行:定义 OUTPUT 过程的结束。
阅读全文