汇编语言第五章(loop)

编程时应该注意什么?

    数据来源        寄存器、内存地址 访问方式: ds:[0] ds:[bx]

    数据的长度:    字节、字

    数据的归宿:     es

    需要记住返回指令:

            mov ax, 4c00h

            int 21h

    psint 指令需要 用 -p 执行

 

现在 来思考一下 2^N 如和计算

嗯,之前写过 2^3是,酱紫的:

        mov ax, 2

        add ax, ax

        add ax, ax

    那么,理论上 2 n次方 就是, 酱紫的

        assume cs:code

        code segment

            start:

                mov ax, 2

                add ax, ax

                add ax, ax

                add ax, ax

                add ax, ax

                add ax, ax

                add ax, ax

                add ax, ax

                add ax, ax

                add ax, ax

                add ax, ax

                ...

                ;执行n次

 

                mov ax, 4c00h

                int 21h

 

            code ends

 

        end start

 

    一点通用性都没有🐎,而且, 不考虑寄存器的限制时 100w 次方我就得写至少

    100w+1行……,

    所以我们来思考一下如和化简?

    嗯,机智如我,嘿嘿!jmp, 可以往回跳 嘿嘿 所以我的代码就成这样了,

    等等, 往哪跳?嗯,是个问题,当初学的 jmp,是跳到一个固定的

    地址,我这个程序,每一次运行地址不会固定啊。赶忙去调戏了一波度娘

    发现jmp 得这样用:

        setNumber:  ;jmp的位置

                    ;中间代码   

                    jmp setNumber

    嗯,当当当当,新的代码:

    

        assume cs:code

        code segment

        start:

                    mov ax, 2

        setNumber:  add ax, ax

                    jmp setNumber

            

                    mov ax, 4c00h

                    int 21h

 

            code ends

 

        end start

 

    绝妙啊,等等,停不下来了,你是嚼了炫迈吗

 

    得再调教一下,寄存器小姐姐拷问划开始……

    ,经过一波 灵魂拷问, 寄存器小姐姐终于屈服了,招出了幕后元凶——迭代器!

    这下,不行了,莫得办法了,只能祭大招了 决定就是你了——loop

        循环指令:loop

            终于等来了超级简化大法!!!

            结构:

                s:  ;代码

                    loop s

                pscx 决定循环次数

    代码就变成这样了:

        assume cs:code

        code segment

 

        start:

                    mov ax, 2

                    mov cx, 3

        s:          add ax, ax

                    loop s

            

                    mov ax, 4c00h

                    int 21h

 

            code ends

 

        end start

 

    打完,收工

 

    这里有一道脑筋转弯,马上就可以鉴别你是不是一个汇编程序员

            用编程进行加法运算 123 * 456,请问如何优化(只能用加法)?

        说出你的想法~

            无比机智的我第一反应就是,把每次相加的结果存储起来,再相加,类似于 2^16次方

        先算 2+2, 再算 4+4, 然后算 8+8,这样只计算次数就可以缩减到 log, 等等

        对数……,对数怎么算啊,凉凉,莫得戏

            转念选项 123 * 456 就是 123 456 ,

            123*456 == 456 * 123,

            ~,成了, 456 计算 123 ,真的少了不少

            2^100w 少的更多...

        真的是机智如我啊

    

    后面就是枯燥的编程题了:我咬发森为莫得情感的刷题机器人

 

1、将内存 FFFF:0 ~ FFFF:F 内存中单元数据赋值到 0:200 ~ 0:20F

    我莫得感情:

        assume cs:code

        code segment

 

        start:

                    mov ax, 0ffffH  ;数字不允许以字母开头

                    mov ds, ax      ;设置数据从哪来

                    

                    mov ax, 20H

                    mov es, ax;     ;设置数据到哪去

 

                    mov bx, 0

                    mov cs, 8       ;初始化

 

        setNumber:  mov dx, ds:[bx]

                    mov es:[bx], dx

                    add bx, 2

 

                    loop setNumber

 

                    mov ax, 4c00h

                    int 21h         

 

        code ends

 

        end start

 

    我觉得我已经狗机制了比一个个字节移动快了一倍,大佬更狗

        assume cs:code

        code segment

 

        start:

                    mov ax, 0ffffH  ;数字不允许以字母开头

                    mov ds, ax      ;设置数据从哪来

                    

                    mov ax, 20H

                    mov es, ax;     ;设置数据到哪去

 

                    mov bx, 0

                    mov cx, 8       ;初始化

 

        setNumber:  push ds:[bx]

                    pop es:[bx]

                    add bx, 2

 

                    loop setNumber

 

                    mov ax, 4c00h

                    int 21h         

 

        code ends

 

        end start

 

    寄存器都省了,临时保存,随时释放.......是在下输了

 

2.  向内存中 0:200 ~ 0:23F 依次传递 数据 0 ~ 63(3FH),程序中只允许有9条指令

    莫得感情的我:(想不出来)

        assume cs:code

        code segment

 

        start:

                    mov ax, 20H     ;数字不允许以字母开头

                    mov es, ax      ;设置数据从哪来

 

                    mov bx, 0

                    mov cx, 64       

                    mov dl, 0       ;初始化

 

        setNumber:  mov es:[bx], dl

                    inc dl

                    inc bx, 2

 

                    loop setNumber

 

                    mov ax, 4c00h

                    int 21h         

 

        code ends

 

        end start

 

    更加莫得感情的大佬:

        assume cs:code

        code segment

 

        start:

                    mov ax, 20H     ;数字不允许以字母开头

                    mov es, ax      ;设置数据从哪来

 

                    mov bx, 0

                    mov cx, 64      ;初始化     

 

        setNumber:  mov es:[bx], bl

                    inc bx

 

                    loop setNumber

 

                    mov ax, 4c00h

                    int 21h         

 

        code ends

 

        end start

 

    但是,老师更加喜欢我这种代码

 

总结:今天肯定不止敲了2000t 和 回车键,没啥好总结的了,该说的都说了

 

 我还写了一个 从 2~N 的 平方的代码,当然溢出我就没办法了(我用了一点第六章的东西)

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

data segment
    dw 0, 1, 2, 3, 4, 5, 6, 7, 8, 9         ;这里的数据可以自行替换

data ends

stack segment
    dw 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0    ;这里是栈的初始化和大小
stack ends

code segment

start:

    mov ax, stack
    mov ss, ax
    mov sp, 20h     ;设置栈定 ss:sp 指向 stack:20

    mov ax, data
    mov ds, ax      ;数据段设置
    
    mov bx, 5*2     ;设置平方的底数

    mov ax, [bx]    
    mov cx, [bx]    
    dec cx          ;设置循环次数,0 ~ n-1    
s:  add ax, [bx]    
    loop s          ;循环的主体,执行完这一句就等于完成了n^2的计算
    
    push ax
    pop dx          ;栈测试

    mov ax, 4c00h
    int 21h

code ends

end start

 

posted @ 2020-03-01 22:11  秦_殇  阅读(815)  评论(0编辑  收藏  举报