如果你想整体移动的话,则可考虑用两个寄存器分别装两个数据,移位一次后,用带进位的加法,让高16位与0相加,然后再进行第二次移位。
至于老师说的用堆栈,估计是因为他想一次性移两位,为了不丢失第一次的进位,则用堆栈加以保存。个人认为这样做更复杂一些。
MOV SI,0
MOV AX,VAR[SI]
MOV CX,01H
SAL AX,CL
INC SI
MOV BX,VAR[SI]
MOV CX,01H
SAL BX,CL
ADC AX,0
以上是我随手想的,没有上机验证,只移动了1位,楼主自己修改吧,注意ADC必须在两个寄存器都移位后,且须紧接着BX(低16位)移位后才能用。
指令编写有错误。ROR循环右移位指令。如果在目标元件中指定了位元件组的组数,在上面程序里,则只有K4M0(16位指令)或K8M0(32位指令)。并且ROR最好是脉冲执行(用RORP)否则每个扫描周期移位一次会看不清楚。
下面是修改后的程序。为了便于仿真,我把X1换成了秒脉冲信号M8013。供你参考。
ROR: 循环右移 *** 作RRX:扩展的循环右移 *** 作
说到用处,我自己感觉并不是很大,因为我们一般用LSR(逻辑右移)和ASR(算术右移),这两种右移方式只是ARM汇编的扩展功能,在实际应用中,好像很少用。
集体使用方法你可以参考杜春雷的介绍ARM的书《ARM体系结构与编程》,我有电子版,你可以给我邮箱,我发给你,这本书18M,百度文库中上传不了。“第三条指令,左移前最高4位都为0,CF为何不是0?”
请你弄清楚CF和AF的概念! CF是8位的,第三条指令,ROL BX,CL
使得0000 1000 1100 1011变成
0100 0110 0101 1000。其中0100 0110 0101 1000的第八位的1,左移3位后,越过第八位,CF=1,走到第十一位。
不懂的话百度Hi我。我们一起学习,我也有考这个。可以使用,这些都是汇编指令
1ASR
算术右移指令数据算术右移,将符号位拷贝到空位,移位结果保存到Rd 中,指令格
式如下;
ASR Rd,Rs
ASR Rd,Rm,#expr
其中 Rd 目标寄存器,也是第一个 *** 作数寄存器必须在R0~R7 之间
Rs 寄存器控制移位中包含移位量的寄存器必须在R0~R7 之间
Rm 立即数移位的源寄存器必须在R0~R7 之间
expr 立即数移位量,值为1~32
2LSR
逻辑左移指令数据逻辑左移,空位清零,移位结果保存到Rd 中指令格式如下
LSR Rd,Rs
LSR Rd,Rm,#expr
其中 Rd 目标寄存器,也是第一个 *** 作数寄存器必须在R0~R7 之间
Rs 寄存器控制移位中包含移位量的寄存器必须在R0~R7 之间
Rm 立即数移位的源寄存器必须在R0~R7 之间
expr 立即数移位量,值为1~32
3ROR
循环右移指令数据循环右移,寄存器右边移出的位循环移回到左边,移位结果保存
到Rd 中,指令格式如下
ROR Rd,Rs
其中 Rd 目标寄存器也是第一个 *** 作数寄存器必须在R0~R7 之间
Rs 寄存器控制移位中包含移位量的寄存器必须在R0~R7 之间
条件标志:指令会更新N,Z,C 的标志(若移位量为零,则不影响C 标志)SHL/SAL一样:逻辑/算术左移,最高位进到CF,最低位补0;
SHR:逻辑右移,最低位进到CF,最高位补0;
SAR:算术右移,最低位进到CF,最高位不变;
ROL:循环左移,最高位进到CF的同时补到最低位;
ROR:循环右移,最低位进到CF的同时补到最高位;
RCL:带进位循环左移,最高位进到CF的,同时CF值补到最低位;
RCR:带进位循环右移,最低位进到CF的,同时CF值补到最高位;
SHLD:双精度左移,第二个 *** 作数移位到第一个 *** 作数,第一 *** 作数进到CF,和逻辑左移类似,低位移到高位;
SHRD:双精度左移,第二个 *** 作数移位到第一个 *** 作数,第一 *** 作数进到CF,和逻辑由移类似,高位移到低位;
这样差不多可以了吧。1-MOV DX,0
2-MOV BX,10 ;除以10的原因:例如假设AX中的二进制数=十进制数1234
--------------那么 1234/10 得余数4(即得到个位数)
--------------这个时候即 余数=原来个位数 这是一个关键
--------------因下面6-对应这句 123/10 会得到余数=3
--------------即余数=原来的十位数
3-DIV BX ;(32位/16位(看DIV的规定))商由AX保存 余数由DX保存
--------------即现在DX=0005h
4-MOV CX,0304H ; ch=03h(用于循环),cl=04h(用于循环移动)
5-ROR DX,CL ; ror为循环右移指令(见后面) 循环右移4位的原因:
-------------- (1)用4位二进制数表示1位16进制数
-------------- (2)循环右移的是保护所得到的余数,即保护个位
6-L1:DIV BL ;商/10 即123/10 等到11-对应指令跳转到这里时
-----------------会变成12/10 等等
-----------------DIV BL(16位/8位)后新的余数被保存到AH 商保存到AL
7-OR DL,AH ;注意OR在这里的用法:为了保护完整6-所得的余数
-----------------其实这时dl=0000
-----------------如果用and的话 会将余数(四位二进制数)中的1抹掉
8-ROR DX,CL ;对应5-,保护剩下的十位,百位等
9-MOV AH,0 ;清0 因为下次循环是用商/bl
---------------而商(16位/8位)是仅仅保存在AL中
10-DEC CH ;ch=ch-1 对应上面 用于控制循环次数
11-JNZ L1 ;循环跳转
--------------循环里共执行了3次ror dx,cl
--------------再加上循环前的5-,所以共执行了4次ror dx,4
--------------即是说原来DX结构 ddddccccbbbbaaaa
--------------执行5-后变成 aaaaddddccccbbbb
--------------第一次执行8- bbbbaaaaddddcccc
--------------第三次执行8-后恢复ddddccccbbbbaaaa结构
--------------而且aaaa=个位 bbbb=十位 等等
--------------问题出现了: 呵呵 照这样推理 dddd=千位
--------------那么万位保存在哪里呢
--------------偶试验的结果是保存到了AL(AX)中
RET ;结束返回
-------------------------------
-------------------------------
左移1位相当2: 是shl指令
例如:
mvo al,6
shl al,1
结果: al=0c
-------------------------------
右移1位相当/2: 是shr指令
例如:
mov al,6
shr al,1
结果:
al=3
------------------------------
指令ror: 循环右移
例如:
mov al,10011100
ror al,1
结果: al=01001110
------------------------------
指令rol: 循环左移
例如:
mov al,10011100
ror al,1
结果: al=00111001
------------------------------记住它的英文全称就能够很好的知道其使用功能
逻辑指令都是按位进行的,就是需要把数写成二进制数,然后一位对应一位的逻辑运算
还有就是逻辑移位都是把移出位放在CF中然后补0,算术移位则是右移时高位不变,左移时跟逻辑移位一样。
SHL
SHift
logic
Left;逻辑左移
SHR
SHift
logic
Right;逻辑右移
SAL
Shift
Arithmetic
Left
算术左移
SAR
Shift
Arithmetic
Right
算术右移
ROL
ROtate
shift
Left
循环左移
ROR
ROtate
shift
Right
循环右移
RCL
Rotate
with
Carry
shift
Left
带进位循环左移
RCR
Rotate
with
Carry
shift
Right
带进位循环右移
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)