注册 登录
编程论坛 汇编论坛

我自己第一次编的汇编程序

zhu224039 发布于 2012-10-01 11:41, 1586 次点击
程序从键盘获取字符,如果不是数字键盘,结束程序,如果是空格表示 数字输入结束  
讲输入的字符ASCII吗 转换成数字 1 2 3 等,再通过输入 a=a*10+b计算出 转换成一个10进制的二进制数存放在shu中
再把 十进制数 对应位转换成ASCII 码  再显示出来

date segment
     shu dw ?
     ascii db 10 dup(?),'$'
date ends
code segment
     assume cs:code,ds:date
     mov ax,date
     mov ds,ax
     mov bx,0
     mov cx,0
node:mov ah,1
     int 21h
     cmp al,20H
     jz node3
     cmp al,30h
     jb over
     cmp al,39h
     ja over
     sub al,48
     mov ah,0
     mov shu,ax
     mov ax,10
     mul bx
     mov bx,shu
     add bx,ax
     inc cx   
     jmp node
node3:cmp cx,0
     jz over
     mov si,offset ascii
     add si,cx
     mov ax,bx
node1: mov dx,0
       mov bx,10
       div bx
       add dl,48
       mov [si],dl
       dec si
loop node1
      mov dx,offset ascii
      mov ah,9
      int 21h
over: mov ah,4ch
      int 21h
code ends
     end

哈哈哈哈哈哈啊啊哈哈

[ 本帖最后由 zhu224039 于 2012-10-1 11:44 编辑 ]
32 回复
#2
zklhp2012-10-01 11:42
学习了
#3
zhu2240392012-10-01 11:45
Z哥哥 卖萌了。我想我可以编计算器了

[ 本帖最后由 zhu224039 于 2012-10-1 11:54 编辑 ]
#4
有容就大2012-10-01 13:36
成功了?
#5
有容就大2012-10-01 18:49
楼主 你的程序我编译通不过。。。
#6
zhu2240392012-10-01 19:03
我编译的很好啊,masm5.0
#7
zhu2240392012-10-01 19:05
回复 5楼 有容就大
我用的是masm5.0 编译没错误啊
程序代码:
date segment
     shu dw ?
     ascii db 10 dup(?),'$'
date ends
code segment
     assume cs:code,ds:date
     mov ax,date
     mov ds,ax
     mov bx,0
     mov cx,0
node:mov ah,1
     int 21h
     cmp al,20H
     jz node3
     cmp al,30h
     jb over
     cmp al,39h
     ja over
     sub al,48
     mov ah,0
     mov shu,ax
     mov ax,10
     mul bx
     mov bx,shu
     add bx,ax
     inc cx  
     jmp node
node3:cmp cx,0
     jz over
     mov si,offset ascii
     add si,cx
     mov ax,bx
node1: mov dx,0
       mov bx,10
       div bx
       add dl,48
       mov [si],dl
       dec si
loop node1
      mov dx,offset ascii
      mov ah,9
      int 21h
over: mov ah,4ch
      int 21h
code ends
     end
#8
有容就大2012-10-01 20:17
回复 7楼 zhu224039
结果正确吗?


MASMPlus运行后 输入一个字符就退出了。

我对这个很感兴趣 但是水平也不咋的 今天搞了半天 搞出来一个在MASMPlus下可以得到结果
不过我这个方法只能计算到四个字节(32位) 而且输入的第一个数有限制 最好不超过8个字符
可以参考下 一起研究这个东西
其实最好用字符串操作 突破范围限制 这个还不会 正在研究中。。。
程序代码:
;#Mode=DOS
;
MASMPlus 单文件代码模板 - 纯 DOS 程序
;
--------------------------------------------------------------------
;
单个文件需要指定编译模式,否则默认是EXE方式,在系统设置中可以设置默认是DOS还是Windows.
;
编译模式自带了DOS/COM/CON/EXE/DLL/LIB这几种,如果有必要,可以更改ide.ini添加新的编译模式
;
当然,更好的是创建为一个工程.更方便及易于管理,使用方法:按Ctrl多选->创建工程.必须有多个文件
assume cs:code, ds:data

data segment
    astr    db    'Please input a:', '$'
    bstr     db    0dh, 0ah, 'Please input b:', '$'
    cstr    db 0dh, 0ah, 'a * 10 + b = ', '$'
    rslt    db    30 dup(?)
    nums    dw 0, 0, 0, 0
data ends

code    segment
start:        mov      ax, data
              mov     ds, ax               

              mov    si, offset nums
              
              mov    dx, offset astr
              mov    ah, 9
              int      21h
              
    aput:       mov    ah, 1
                int    21h
                cmp    al, 0dh
                jz        bput
                call    multen
                mov    ah, 0
                sub    al, 30h
                add    [si], ax
                adc    [si + 2], 0
                jmp     aput
               

    bput:        mov    dx, offset bstr
                mov    ah, 9
                int    21h
        b1:    mov    ah, 1
                int    21h
                cmp    al, 0dh
                jz        cput
                mov    si, offset nums
                add    si, 4
                call    multen
                mov    ah, 0
                sub    al, 30h
                add    [si], ax
                adc    [si + 2], 0
                jmp    b1
               

    cput:        mov    dx, offset cstr
                mov    ah, 9
                int      21h
                mov    si, offset nums
                call    multen
                mov    ax, [si]
                mov    dx, [si + 2]
                add     ax, [si + 4]
                adc    dx, [si + 6]
                mov    si, offset rslt
                mov    di, 0
        c1:    mov    cx, 10
                call     divdw
                add    cx, 30h
                push    cx
                inc    di
                cmp    ax, 0
                jz        c2
                jmp    c1
        c2:    cmp    dx, 0
                jz        c3
                jmp     c1
        c3:    mov     cx, di
            c4:
                pop     ax
                mov    [si], al
                inc    si
                loop c4
                mov    al, '$'
                mov    [si], al
              
                mov    dx, offset rslt
                mov     ah, 9
                int     21h
                mov    ah, 1
                int     21h
                mov    ax, 4c00h
                int     21h
               

divdw:        push    si
                push  bx
                push    ax
               

                mov    ax, dx
                mov    dx, 0
                div    cx
                mov     si, ax
                pop     ax
                div    cx
                mov    cx, dx
                mov    dx, si
              
                pop    bx
                pop     si
                ret

multen:        push     ax
                push    dx
                xor    ax, ax
               

                shl    WORD ptr [si + 2], 1
                shl     WORD ptr [si], 1
                adc    WORD ptr [si + 2], 0
                mov    ax, [si]
                mov    dx, [si + 2]
               

                shl    WORD ptr [si + 2], 1
                shl     WORD ptr [si], 1
                adc    WORD ptr [si + 2], 0
                shl    WORD ptr [si + 2], 1
                shl     WORD ptr [si], 1
                adc    WORD ptr [si + 2], 0
               

                add    [si], ax
                adc    [si + 2], dx
               

                xor    ax, ax
                pop    dx
                pop    ax
                ret
code    ends

end start
晕 为什么我排版整整齐齐的发上来就乱七八糟的了 很多次了 为什么啊

只有本站会员才能查看附件,请 登录



[ 本帖最后由 有容就大 于 2012-10-1 20:29 编辑 ]
#9
有容就大2012-10-01 20:50
楼主 有没有兴趣一起写个:两个大数相加的程序?
#10
zklhp2012-10-01 20:58
以下是引用有容就大在2012-10-1 20:50:46的发言:

楼主 有没有兴趣一起写个:两个大数相加的程序?

这个还是用C写罢 挺复杂的 汇编写起来太麻烦了
#11
有容就大2012-10-01 21:05
以下是引用zklhp在2012-10-1 20:58:26的发言:


这个还是用C写罢 挺复杂的 汇编写起来太麻烦了

相加相对简单些 相乘就麻烦了。
喜欢这种感觉 还只用16位汇编 哈哈。。。
#12
zhu2240392012-10-01 21:56
回复 11楼 有容就大
我上面的代码 不是计算功能

只是从键盘获取  数字字符,以 空格键 为数据输入结束的标志
也就是 1 2 3 4 空格是合法的  其他的  1 2a34,就会自动结束程序的
 
功能是将 数字字符组合 ‘1’‘2’ 转换成 十进制数 12  存放到shu的地址里

然后再将 二进制12  显示在屏幕上

完成的动作  是从键盘上获取十进制数,并打印出 十进制数

和scanf(%d)  printf(%d)  功能类似
#13
zhu2240392012-10-01 21:59
回复 9楼 有容就大
有哇,你给讲讲程序要满足什么要求

对了 微机原理 里说 DOS只能管理 640KB的内存空间是什么意思啊,不是1MB吗?
#14
zhu2240392012-10-01 22:06
大数 16位寄存器 也就AX BX CX DX  这几个寄存器,分别可以放 4个 字的内容  也就是 最大的无符号数为 2的 16*4 次方
采用高位+高位+CF 低位+低位  +  -

BCD码 计算方式 可以借用
#15
zhu2240392012-10-01 22:06
长老有什么好想法
#16
有容就大2012-10-01 22:15
以下是引用zhu224039在2012-10-1 21:59:12的发言:

有哇,你给讲讲程序要满足什么要求

对了 微机原理 里说 DOS只能管理 640KB的内存空间是什么意思啊,不是1MB吗?

DOS只能用内存空间低端的640KB
系统硬件要用到从A0000H~FFFFFH,共384KB的地方。其中有用于显示的视频缓冲区和BIOS程序空间,例如显卡,网卡和主板BIOS。
#17
有容就大2012-10-01 22:18
以下是引用zhu224039在2012-10-1 22:06:01的发言:

大数 16位寄存器 也就AX BX CX DX  这几个寄存器,分别可以放 4个 字的内容  也就是 最大的无符号数为 2的 16*4 次方
采用高位+高位+CF 低位+低位  +  -

BCD码 计算方式 可以借用

感觉关键是用BCD码 注意循环 理论上相加的两个数的长度没有限制 根据你开出的 xxx dup(?)而定。
#18
zhu2240392012-10-01 22:19
书上也是这么说的 ,为什么是640KB 而其他的地方不能用呢
#19
madfrogme2012-10-01 22:21
最近也在看汇编,不为别的,就为了看懂linux 0.11内核的boot process 的那3个文件
bootsect.s setup.s head.s
不过貌似是对时间,金钱,人品的考验

可有能助我一臂之力者

[ 本帖最后由 madfrogme 于 2012-10-1 23:22 编辑 ]
#20
zhu2240392012-10-01 22:25
回复 17楼 有容就大
乘法  怎么办呢   
除法
#21
zhu2240392012-10-01 22:29
回复 19楼 madfrogme
王爽版  汇编语言里  有个 更改中断向量表 的程序
其中有个加载的 过程 目测对你有帮组
存储器里 有分段 分页的管理  嘿嘿  你可以模仿
#22
有容就大2012-10-01 22:30
回复 18楼 zhu224039
其实640KB是常规内存吧 如果是在纯DOS下 他的应用程序都在低端的常规内存活动 不给他权限去操作
高端内存 这个是微软和IBM在设计DOS操作系统时定的规矩
如果真要突破这个限制 貌似也可以
不过这个问题太久远了 没怎么研究过
#23
有容就大2012-10-01 22:32
以下是引用zhu224039在2012-10-1 22:25:33的发言:

乘法  怎么办呢   
除法

呵呵 我也是才研究这个问题 等把加法写出来才能有可能攻克乘除。
#24
madfrogme2012-10-01 22:33
回复 21楼 zhu224039
我试试看,谢谢~~~
#25
信箱有效2012-10-01 22:34
以下是引用madfrogme在2012-10-1 22:21:26的发言:

最近也在看汇编,不为别的,就为了看懂linux 0.11内核的boot process 的那3个文件
bootsect.s setup.s head.s
不过貌似是对时间,金钱,人品的考验
 
可有能助我一臂之力者
为什么非要看这个呢?
又为什么非要看懂捏
有什么迫切的需求?
#26
有容就大2012-10-01 22:35
以下是引用madfrogme在2012-10-1 22:21:26的发言:

最近也在看汇编,不为别的,就为了看懂linux 0.11内核的boot process 的那3个文件
bootsect.s setup.s head.s
不过貌似是对时间,金钱,人品的考验
 
可有能助我一臂之力者

呵呵 汇编作用还蛮大。
#27
zhu2240392012-10-01 22:38
不清楚,因为上层的东西 都是下层的支持,没有下层 哪有上层的演化。从底层学起

他估计是想写操作系统吧
#28
zhu2240392012-10-01 22:40
我去看看BCD码  关于乘法方面的 指令去了  嘿嘿
#29
madfrogme2012-10-01 22:43
以下是引用信箱有效在2012-10-1 23:34:00的发言:

为什么非要看这个呢?
又为什么非要看懂捏
有什么迫切的需求?

太太太太太有迫切需求了,最近看到一个MikeOS, 在虚拟机上运行了一下,有点小激动,并且只有400多K,所以一个人写一个像linux一样的操作系统当然不可能,但写一个支持内存管理,文件系统的小的OS还是完全有可能滴~~
所以对我来说首要任务就是对80386 的认识和 boot process 了了了了了
#30
zhu2240392012-10-01 22:47
80386  嘿嘿 我正在看 这章节的
微型计算机原理接口技术

里面的 分段 和分页 管理 模式   对你有用哟

估计你还得去了解BIOS 引导 部分,将自己的程序入口加载到那去

王爽  那个更改  向量中断表的 列子 估计能帮上你忙
#31
zhu2240392012-10-01 22:48
只是目测哟,我只是个学生 浅见  见笑了
#32
madfrogme2012-10-01 22:50
好的,时不时也欢迎到linux教室做客,我有时也会在那里贴点这方面的东西,希望多提意见
#33
zhu2240392012-10-01 22:51
1