文章随机晒最新文章关照最多的

jiayi Rss

汇编 输出数字

| Posted in Assembly |

9

汇编确实够傻,平时百用不爽的类似 printf("%dn",i)输出数字竟找不到现成的实现…汇编系统调用默认输出的是其ASCII码…

输出数字,在学习编程语言的时候还是经常用到的,比如比较个大小,排个序…一时间不能输出,郁闷至极,遂写个程序实现 有符号整形 的输出。因为学习汇编不久,像宏的实现,函数的调用当作练手之用都堆了上去,所以程序显得比较臃肿、业余。。。

环境:Linux NASM+ald (因为NASM 支持的intel 汇编和上课学的DOS下汇编语法差不多,为了考试,先用它。AT&T以后再说……),NASM 的具体应用请看其手册:http://www.nasm.us/doc/nasmdoc0.htmlald 看其帮助即可

下面的程序将 val 中的数值输出

CODE

;print_int.asm

SECTION .DATA
        val DD -10H
        len EQU $-val
        newline DB 0xA

%macro write 2  ;屏幕打印的宏
        MOV     eax, 4
        MOV     ebx, 1
        MOV     ecx, %1
        MOV     edx, %2
        INT     80h
%endmacro

print:  ;循环打印函数
        loop1:
                PUSH    ECX             ;write 要对ECX作修改,为保证循环正常,将ECX 压入栈中暂存
                write   EBP, len
                POP     ECX
                ADD     BP, 4
        LOOP loop1
        write   newline, 1     
RET

change_to_positive:     ;负数->正数
        DEC     EAX
        NOT     EAX
        MOV     [flag], BYTE 1H
RET

SECTION .bss
        flag RESB 1

SECTION .TEXT
GLOBAL _start
_start:
        MOV     EAX, [val]
        MOV     [flag], BYTE 0H ;初始化正负标记
        CMP     EAX, 0
        JGE     go_on                   ;和0 作比较,大的话跳至go_on
        CALL    change_to_positive      ;小的话,调用函数,将负数调整为对应的正数
go_on: 
        MOV     CL, 4
        MOV     EDX, 0
put_to_stack:  
        INC     EDX             ;每有一个byte入栈,计数寄存器EDX 加一
        MOV     EBX, EAX        ;EAX 的数传给EBX 作处理
        AND     EBX, 0FH        ;EBX 与 1111B 按位与,得到最地位数字
        ADD     EBX, ‘0’       ;作ASCII码调整
        PUSH    EBX             ;调整好的码压入栈中
        SHR     EAX,CL          ;EAX 右移4位
        JNZ     put_to_stack    ;EAX 如果不为0,继续 put_to_stack
        JZ      print_int       ;EAX 如果为0,说明处理完毕,跳至打印标签处打印
print_int:
        CMP     [flag], BYTE;比较符号标志位,0为正,1为负
        JZ      go_on2  ;0的话,直接输出
        MOV     EBX,‘-‘
        PUSH    EBX     ;1的话,将’-‘压入栈中
        INC     EDX     ;因为多了一个byte的’-‘,所以EDX 要加一
go_on2:
        MOV     EBP, ESP        ;ESP的地址传给EBP
        MOV     ECX, EDX        ;循环控制数传给ECX
        CALL    print           ;调用循环打印函数
        POP     EAX
_exit:
        MOV     EBX, 0
        MOV     EAX, 1
        INT     0x80

编译 连接 运行如下:
jiayi:/mnt/3/asm # ./print_int
-10
jiayi:/mnt/3/asm #

要期中考试了,封装的事考完再折腾…

还有,应Jobru 童鞋的建议,代码背景颜色做了改动,不知顺眼否~

Comments (9)

沙发 呵呵

555555555555……….我汇编的课程还落下了 。。 得赶紧补回来

……换了背景色还是难看啊^_^

@daniel
汇编不学不给过啊…加油~

@JoBru
太坏了。。。
先这样吧,反正比前面的好看^_^

好好学习天天向上

又更新了 赶快学习

继续学习中

8懂,偶是纯文科的

Write a comment

You must be logged in to post a comment.