鱼C论坛

 找回密码
 立即注册
查看: 463|回复: 3

[已解决]AL与AX的区别,读取地址什么时候会将高位同时读下来,如何辨别

[复制链接]
发表于 2024-8-2 22:21:21 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能^_^

您需要 登录 才可以下载或查看,没有账号?立即注册

x
题目:将A,B中的的值相加到D中
ASSUME CS:CODE
A SEGMENT
    DB 1,2,3,4,5,6,7,8
A ENDS
B SEGMENT
    DB 1,2,3,4,5,6,7,8
B ENDS
D SEGMENT
    DB 0,0,0,0,0,0,0,0
D ENDS
CODE SEGMENT
START: MOV AX,A
       MOV DS,AX;DS段寄存器
       MOV AX,B
       MOV ES,AX;ES段寄存器
       MOV BX,0
       MOV AX,D
       MOV SS,AX;SS段寄存器
       MOV CX,8
S:     MOV AL,[BX]
       MOV SS:[BX],AL
       MOV AL,ES:[BX]                        ;这个循环在debug中我发现用AX代替AL结果不变都是 02 04 06 08 0A 0C 0E 10-00
       ADD SS:[BX],AL                                请问什么时候AX,AL两者有区别呢       
       INC BX
       LOOP S
       MOV AX, 4C00H
       INT 21H
CODE ENDS
END START
最佳答案
2024-8-2 23:20:03
AX 和 AL 的区别
在x86架构中,AX是一个16位的寄存器,而AL是AX寄存器的低8位。这意味着当你操作AL时,你实际上是在操作AX的低8位,而AX的高8位(AH)保持不变。在你的代码中,当你使用MOV AL, [BX]和MOV AL, ES:[BX]时,你是在从相应的内存地址加载数据到AL(即AX的低8位)。然而,当你执行ADD SS:[BX], AL时,这个加法操作只影响SS:[BX](即D段中的相应字节),对AX的高8位(AH)没有任何影响。

代码中的问题
错误的段寄存器使用:
在你的代码中,你试图将D段的地址加载到SS(堆栈段寄存器)中。这是不正确的,因为SS是用于堆栈的,而D段看起来像是用于存储数据的。你应该使用一个不同的段寄存器(如DS)来访问D段。然而,在这个特定的例子中,因为你已经设置了DS来访问A段,你可能想保持DS不变,并使用一个不同的方法来指定D段的地址。
使用OFFSET来定位D段:
为了访问D段的数据,你可以使用OFFSET指令来获取D段的偏移地址,并将其加载到一个寄存器中(比如BX或DI),然后结合DS(或另一个段寄存器,如果你选择改变它)来访问D段的数据。
循环和累加:
你的循环逻辑本身是正确的,但在处理D段数据时需要注意上述问题。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2024-8-2 22:23:42 | 显示全部楼层
好的,让我们来聊聊AL与AX的区别,以及你的代码中提到的读取地址的问题。

### AL与AX的区别

首先,AL和AX都是寄存器,通常我们用AX表示一个16位的寄存器,而AL则是AX的低8位部分。可以想象成AX就像是一个装满了糖果的大罐子(16个糖果),而AL就是这个大罐子里最底下的那8个糖果。你可以将AL当做AX的一部分,但不能说AL能独立开来,除非你不想吃掉顶部的8个糖果。

**简单总结:**
- **AX** 是16位(包含AL和AH)
- **AL** 是AX的低8位部分

### 读取地址时高位的处理

在大多数情况下,当你使用16位寄存器(比如AX)来访问内存,处理器会自动管理高位和低位。比如当你加载一个16位数的时候,如果这个数需要被分拆成高位和低位,系统会自己把高位(AH)和低位(AL)一起处理。但如果你只指明了AL,那这时候它就只拿走了低8位的内容,即使高8位(AH)可能还是存在的。

### 如何辨别什么时候用AX、AL

通常来说,你需要考虑以下几点来决定使用AX还是AL:
- **要处理的数据大小**:如果你在处理一个16位的数据(如某个计算或地址),那么就用AX;如果你只关心低8位,那么使用AL。
- **操作指令要求**:某些指令只接受8位操作数,此时必须使用AL。如果是要进行更复杂的操作,例如加法或者其他算术运算,通常需要AX。

### 关于你的代码问题

在你的代码中,循环体内:
MOV AL, ES: ; 用AX代替AL
ADD SS:, AL

如果你用AX代替AL,而没有显式用AH,AS就会包含高8位的数据,可能会导致你的结果不变,因为你只在操作AL,这意味着你只是在改变SS中的低位数据,而高位(AH)保持不变。所以如果你只使用AL,你实际上是在只对8位数据进行操作,而没有把高位(0)作任何改动。

由于你提到运行结果不变,可以在循环中添加一些调试信息,看看在每一步AL和AX的值到底是什么样的,这样就能帮助你更好地理解它们在内存操作中的表现。

希望这些解释能够帮助你更好地理解AL和AX的使用差异!如果还有其他问题,随时问我哦!

以上回复来自 FishC AI 小助理,如未能正确解答您的问题,请继续追问。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2024-8-2 23:20:03 | 显示全部楼层    本楼为最佳答案   
AX 和 AL 的区别
在x86架构中,AX是一个16位的寄存器,而AL是AX寄存器的低8位。这意味着当你操作AL时,你实际上是在操作AX的低8位,而AX的高8位(AH)保持不变。在你的代码中,当你使用MOV AL, [BX]和MOV AL, ES:[BX]时,你是在从相应的内存地址加载数据到AL(即AX的低8位)。然而,当你执行ADD SS:[BX], AL时,这个加法操作只影响SS:[BX](即D段中的相应字节),对AX的高8位(AH)没有任何影响。

代码中的问题
错误的段寄存器使用:
在你的代码中,你试图将D段的地址加载到SS(堆栈段寄存器)中。这是不正确的,因为SS是用于堆栈的,而D段看起来像是用于存储数据的。你应该使用一个不同的段寄存器(如DS)来访问D段。然而,在这个特定的例子中,因为你已经设置了DS来访问A段,你可能想保持DS不变,并使用一个不同的方法来指定D段的地址。
使用OFFSET来定位D段:
为了访问D段的数据,你可以使用OFFSET指令来获取D段的偏移地址,并将其加载到一个寄存器中(比如BX或DI),然后结合DS(或另一个段寄存器,如果你选择改变它)来访问D段的数据。
循环和累加:
你的循环逻辑本身是正确的,但在处理D段数据时需要注意上述问题。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2024-8-3 06:44:04 | 显示全部楼层
本帖最后由 三体人的智子 于 2024-8-3 06:51 编辑

在上述代码中,AL 是 AX 的低 8 位。

一般来说,在涉及 8 位操作时使用 AL,在涉及 16 位操作时使用 AX。

在这个循环中,由于每次操作的是一个字节(8 位)的数据,所以使用 AL 或 AX 的低 8 位效果相同。

但如果指令明确要求是 8 位操作数,例如与 8 位立即数进行运算或存储到 8 位的存储单元,就必须使用 AL如果是 16 位的操作,例如与 16 位立即数进行运算或存储到 16 位的存储单元,就应该使用 AX。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2024-11-22 00:00

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表