8086汇编作业疑问:数组初始化及MOV AX,PODACI指令含义
MOV AX,PODACI指令的疑问解答 我来帮你拆解这些汇编相关的疑问,一步步理清楚:
一、dw定义的数组在内存里到底是怎么初始化的?
当你用dw(Define Word,定义字)来声明数组时,每个元素会占2字节的内存空间,按照你写的顺序依次存在数据段里(假设你把数组放在数据段)。举个实际例子:
; 初始化两个各10个元素的数组 DATA_SEG segment TABELA dw 1, 3, 5, 7, 9, 2, 4, 6, 8, 10 ; 10个2字节元素 TABELA1 dw 11,13,15,17,19,12,14,16,18,20 DATA_SEG ends
在x86默认的小端模式下,内存里的存储是这样的:
- TABELA的起始地址处,第一个元素
1会被存成0x01 0x00(低字节在前,高字节在后) - 第二个元素
3存成0x03 0x00,以此类推 - TABELA1会紧跟在TABELA的最后一个元素后面,所以它的起始地址就是TABELA的起始地址加上
10*2=20字节
要是你用dw 10 dup(?)定义未初始化的数组,汇编器会在数据段里预留20字节的空间,里面的值要么不确定,要么在部分环境里默认初始化为0。
二、MOV AX,PODACI到底是什么意思?
这里核心得看PODACI是啥类型的标识符,分两种常见情况:
如果PODACI是数据段的段名
大概率你的代码结构是这样的:PODACI segment TABELA dw 10 dup(?) TABELA1 dw 10 dup(?) PODACI ends CODE_SEG segment start: mov ax, PODACI ; 把PODACI段的段地址加载到AX mov ds, ax ; 把AX的值传给DS寄存器,设置当前要访问的数据段 ; 后面操作数组的代码 CODE_SEG ends end start这种情况下,
MOV AX,PODACI是把数据段PODACI的段地址放到AX里,目的是给DS寄存器赋值——毕竟x86汇编里访问内存得先告诉CPU要读哪个段的内容,这是设置数据段的标准操作,和数组元素本身没关系。如果PODACI是TABELA数组的别名/标号
要是你写了PODACI equ TABELA,或者直接把数组叫PODACI,那得注意两种写法的区别:- 直接写
MOV AX, PODACI会报错!因为PODACI是个内存地址,要把地址加载到AX得加OFFSET关键字,正确写法是MOV AX, OFFSET PODACI,这时候AX里存的是数组的偏移地址(相对于数据段起始位置的偏移量)。 - 要是写
MOV AX, [PODACI],这才是把数组的第一个2字节元素读到AX里。
- 直接写
你纠结的“是把两个数组的首个元素地址还是元素本身移入AX”——这两种情况都不沾边,除非PODACI是个存了两个数组地址的结构,但一般不会这么写。更可能的是它是数据段的段名,用来设置DS寄存器。
三、用dw定义数组完全可行!
dw就是x86汇编里定义2字节元素数组的标准指令,完美匹配你的需求。后续要给偶数元素乘2的话,可以遍历数组,判断元素奇偶性,然后用左移1位(shl ax,1)或者自身相加(add ax,ax)来实现乘2,给你个简单的遍历示例(假设已经设置好DS寄存器):
; 遍历TABELA数组,给偶数元素乘2 mov bx, OFFSET TABELA ; 用BX指向数组起始位置 mov cx, 10 ; 循环次数设为10次 loop_start: mov ax, [bx] ; 把当前元素读到AX里 test ax, 1 ; 测试最低位,判断是不是偶数(最低位为0就是偶数) jnz skip_mult ; 要是奇数,就跳过乘2操作 shl ax, 1 ; 偶数的话左移1位,等价于乘2 mov [bx], ax ; 把结果存回数组原来的位置 skip_mult: add bx, 2 ; BX加2,移动到下一个元素(每个元素占2字节) loop loop_start ; 循环直到CX减到0
内容的提问来源于stack exchange,提问作者nick_name

