marquee 循环显示变量_汇编语言 利用宏实现1+2+3....+100 并显示结果:5050

d1a5d7dce67c2f7e1eec8e44680c91d7.png

利用宏实现1+2+3…+100 并显示结果:5050

stack segment
dw 521 dup(?) ;申请栈空间 为保护变量使用
stack ends

data segment
string db 'hell,everybody',0dh,0ah,'$'
table equ this byte  ;存储单元别名操作符THIS:它为同一存储单元取另一别名-table,该别名可具有其自身的数据属性,但其段地址和偏移量是不变的

count=1

rept 100
db count   ;重复汇编
count=count+1
endm

data ends

code segment
assume cs:code,ds:data,ss:stack

start:
mov ax,data
mov ds,ax

mov dx,offset string ;显示 字符串 hello world
mov ah,9
int 21h

mov ax,0
mov si,offset table
mov cx,100

;开始循环累加 
sum:
add al,[si]
adc ah,0
inc si
loop sum

mov dx,0
mov cx,1000
div cx
push dx ;这里很重要 利用栈保护dx的值 不然 后面add dl,30h后 会破坏原来dx的值 而dx的值是余数 不可以被破坏
mov dl,al
add dl,30h
mov ah,02h
int 21h
pop dx  ;恢复dx的值

;提取百位
mov ax,dx
mov cl,100
div cl
mov dl,al
add dl,30h
mov ch,ah

mov ah,02h
int 21h

;提取十位
mov al,ch
mov ah,0
mov cl,10
div cl

mov ch,ah
mov dl,al
add dl,30h
mov ah,02h
int 21h

mov dl,ch
add dl,30h
mov ah,02
int 21h

jieshu:
mov ax,4c00h
int 21h
code ends
end start

结果

4b6b82bb807c6bdaef80f9dc690e1e52.png

注意:

table equ this byte

这句代码的意思:对于下方宏定义的100个存储了1–100的地址 我们必须有个变量指向其首地址 这样我们才可以通过首地址获得第一个变量及以后的变量
在代码段,table所指向的就是存储元素为1的地址。

举例
存储单元别名操作符THIS:它为同一存储单元取另一别名,该别名可具有其自身的数据属性,但其段地址和偏移量是不变的。
操作符THIS的一般格式为: THIS 数据类型
其中:数据类型就是常用的数据类型:BYTE、WORD、DWORD、NEAR和FAR等。
如:
LABC EQU THIS BYTE
LABD DW 4321H, 2255H
这样就给同一片存储单元LABD,取了二个具有不同数据类型的变量名。于是,在指令中,引用不同的变量名,就使用其不同的数据属性:

  • 如果引用变量名LABD,是按“字”属性来访问;
  • 如果引用变量名LABC,是按“字节”属性来访问。
    如此一来,指令“MOV AL,LABC
    ”和“MOV AL,byte ptr LABD
    ”是等效的,所不同的是:当以“字节”属性访问LABD存储区时,不必使用强制属性符PTR,而改用“字节”属性变量LABC即可

易错:

mov dx,0
mov cx,1000
div cx
push dx ;这里很重要 利用栈保护dx的值 不然 后面add dl,30h后 会破坏原来dx的值 而dx的值是余数 不可以被破坏
mov dl,al
add dl,30h
mov ah,02h
int 21h
pop dx  ;恢复dx的值

这里最容易错的地方,就是不用栈存储原来dx的值,因为dx中存储的是除以1000之后的余数,但是为了显示一个字符,我们 add dl,30h 这样一来,会破坏dx的值 ,导致后面出错。
为了避免这种情况的发生,我们应该对dx的值进行保护,这里可以利用栈实现,先入栈dx,后需要的时候再出栈即可。

2.进行循环递加后,其实ax中存储的值是13ba,是十六进制,其实汇编都是对十六进制进行处理,在除以1000的时候,我们认为是5050/1000=5,但是计算机却是先把1000转换为十六进制后,在进行除法,但是,结果还是5.和我们需要的一致。为了显示在电脑上,其实就是利用ASICC输出。5的ASICC是35,所以需要加30h

3.在循环递加时,有人会问,可以用下面这个式子吗?

sum:
add ax,[si]
inc si
loop sum

实验结果证明,不行

32c2e0a2d3954b18906eb749ece3298c.png


利用单步调试可以看出,一开始加1,结果却是0201,不是我们希望的0001。这是因为偏移量为si的地址,存储的值1其实是在低八位,高八位不一定为0哦。所以用add al,[si]

4.对于为什么要进位?这是因为,我们所说的低八位、高八位,其实就是8位2进制数,最大就是11111111=255,而结果5050>255,所以必须利用进位存在ax中。

1281fd04953fe4015ae9395940acd573.png
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值