在实模式下,假设(DS)=1234H,(SI)=124H,(12464H)=30ABH,(12484H)=464H,有以下程序段: LEA SI,[SI] MOV AX,[BX] MOV [SI+22H],1200H LDS SI,[SI+20H] ADD AX,[SI] 上述程序段执行后 (DS)= , (SI)= , (AX)= 。
时间: 2024-04-02 21:37:43 浏览: 148
根据程序段执行后的结果,我们可以逆推出程序执行前的内存状态。
首先,LEA指令将SI的值更新为[SI],即124H处的值30ABH。因此,此时(SI)=30ABH。
接着,MOV AX,[BX]将[BX]处的值读入AX寄存器。由于程序段中没有给出[BX]的值,我们无法确定AX的值。
然后,MOV [SI+22H],1200H将1200H写入[SI+22H]处,即30ABH+22H=30CDH处。因此,此时(30CDH)=1200H。
继续执行,LDS SI,[SI+20H]指令将[SI+20H]处的值作为地址加载到DS:SI中。由于此时(SI)=30ABH,因此DS:SI指向(30ABH+20H)=30CBH处的内存单元。根据该内存单元中的值,将DS设置为464H,SI设置为1234H。因此,此时(DS)=464H,(SI)=1234H。
最后,ADD AX,[SI]将AX和[SI]处的值相加,并将结果存回AX中。由于此时(SI)=1234H,因此[SI]处的值为(1234H)=464H。因此,AX的值为原来的值加上464H。
综上所述,程序段执行后,(DS)=464H,(SI)=1234H,(AX)的值取决于[BX]的值,无法确定。
相关问题
编写汇编语言代码程序,将一组数(0123h,0456h,0789h,0abch,0defh,0fedh,0cbah,0987h)和另一组数据(0234h,0345h,0456h,0567h,0678h.0789h,089ah,09abh)依次两两相加,将相加结果逆序存储到新的段中
编写汇编语言程序来完成这个任务涉及到几个步骤,这里是一个基于x86架构的示例,假设我们使用Intel 8086汇编语言:
1. **声明变量和内存空间**:
- 首先,我们需要为原始数值、临时储存的结果以及最终逆序存储的数据分配内存区域。
- 对于输入的两个数组,每个元素占用1字节,我们可以假设最多16对数值。
2. **加载数据**:
- 使用LODS (Load Effective Address) 指令从源数组开始逐个加载数字到寄存器或内存地址。
3. **处理两两相加**:
- 使用ADD指令将当前的两个数值相加,结果可能会超过一个字节,所以可能需要拆分结果并分别存储在相邻的内存位置。
4. **存储结果**:
- 使用STOSW (Store Word) 或 STOSB (Store Byte) 指令把两个字节的结果存入目标内存区。如果结果溢出,可能需要调整存放位置。
5. **遍历数组**:
- 使用循环结构(如REPE MOVSB或LOOP指令),对于每一对数值进行相加操作,并更新指向下一组数值的指针。
6. **逆序存储**:
- 添加额外的逻辑来确保存储结果时按照逆序的方式,这通常通过一个倒序循环或临时数组辅助进行。
7. **结束循环**:
- 当所有的相加和存储操作完成后,跳出循环。
8. **清理内存**:
- 最后,记得释放不再使用的内存资源。
```assembly
; 假设源数据段在DS, 目标数据段在ES, 起始地址分别为OFFSET SRC1 和 OFFSET DST
; 定义必要的内存偏移
OFFSET_SRC1 equ 0x01 ; 原始数据1的起始地址
OFFSET_DST equ 0x10 ; 存储结果的起始地址
; 循环处理数据
mov cx, 16 ; 总共16对数据
mov di, OFFSET_DST ; 初始化目标指针
mov si, OFFSET_SRC1 ; 初始化源指针
loop_start:
lodsb ; 加载源1的第一个字节
add al, [si+1] ; 加上源2的第一个字节
stosb ; 存储结果
lodsw ; 加载源1的下一个字节
add ax, [si+2]
stosw ; 存储结果
; 如果有溢出,需处理
; ...
inc si ; 更新源指针
dec di ; 更新目标指针
loop loop_start ; 继续下一对数据,直到cx减至0
; 逆序存储部分代码略...
```
假设数据段从BUF单元开始,存有20个字节的有符号数。请编写一个完整源程序实现: (1)将其中的非负数送数据段PLUS开始的若干单元。 (2)统计非负数的个数,并以十六进制的形式显示在屏幕上,显示格式为: NUM=非负数个数H。
下面是一个完整的源程序,可实现将数据中的非负数送到PLUS单元,并统计非负数的个数并以十六进制形式显示在屏幕上:
```
.MODEL SMALL
.STACK 100H
.DATA
BUF DB 7FH, 0F0H, 0FFH, 80H, 0ABH, 0CDH, 0EFH, 12H, 34H, 56H, 78H, 9AH, 0BDH, 0DEH, 0EFH, 0F1H, 23H, 45H, 67H, 89H
PLUS DB 20 DUP (?)
COUNT DB 0
.CODE
MOV AX, @DATA
MOV DS, AX ; 初始化数据段寄存器
MOV CX, 20 ; 数据段中共有20个字节的数据
MOV SI, 0 ; 从BUF单元开始
MOV BX, OFFSET PLUS ; PLUS单元起始地址
LOOP1:
CMP BYTE PTR BUF[SI], 0 ; 判断是否为非负数
JNL MOVE ; 如果是非负数,跳转到MOVE
INC SI ; 如果是负数,继续循环
LOOP LOOP1 ; 继续处理下一个字节
JMP FINISH ; 处理结束,跳转到FINISH
MOVE:
MOV AL, BUF[SI] ; 将非负数存入PLUS单元
MOV BYTE PTR [BX], AL
INC BX ; PLUS单元地址+1
INC COUNT ; 统计非负数个数
INC SI ; 数据段地址+1
LOOP LOOP1 ; 继续处理下一个字节
FINISH:
; 将非负数个数以十六进制形式显示在屏幕上
MOV AH, 09H ; 选择显示字符串的功能
MOV DX, OFFSET MSG ; 显示提示信息
INT 21H
MOV AH, 02H ; 选择显示一个字符的功能
MOV DL, ' '
INT 21H
MOV AH, 04H ; 选择显示一个数字的功能
MOV AL, COUNT ; 非负数个数
CALL HEX ; 将数字转换为十六进制
INT 21H
MOV AH, 4CH ; 退出程序
INT 21H
; 将数字转换为十六进制
HEX PROC
PUSH AX ; 保存寄存器状态
MOV AH, 00H ; AH=0
MOV BL, 0AH ; BL=10
DIV BL ; AL/BL,商在AH中,余数在AL中
CMP AH, 0 ; 判断商是否为0
JZ ENDHEX ; 如果为0,跳转到ENDHEX
CALL HEX ; 递归调用HEX
ENDHEX:
POP AX ; 恢复寄存器状态
CMP AL, 0AH ; 判断余数是否大于9
JL LESS ; 如果小于等于9,跳转到LESS
ADD AL, 07H ; 如果大于9,将余数加上7
LESS:
ADD AL, 30H ; 加上30H,得到ASCII码
MOV DL, AL ; DL=AL
MOV AH, 02H ; 选择显示一个字符的功能
INT 21H
RET ; 返回调用程序
HEX ENDP
MSG DB 'NUM=', 0
END
```
阅读全文