汇编确实够傻,平时百用不爽的类似 printf("%dn",i) 的输出数字竟找不到现成的实现…汇编系统调用默认输出的是其ASCII码…
输出数字,在学习编程语言的时候还是经常用到的,比如比较个大小,排个序…一时间不能输出,郁闷至极,遂写个程序实现 有符号整形 的输出。因为学习汇编不久,像宏的实现,函数的调用当作练手之用都堆了上去,所以程序显得比较臃肿、业余。。。
环境:Linux NASM+ald (因为NASM 支持的intel 汇编和上课学的DOS下汇编语法差不多,为了考试,先用它。AT&T以后再说……
),NASM 的具体应用请看其手册:http://www.nasm.us/doc/nasmdoc0.html 。 ald 看其帮助即可
下面的程序将 val 中的数值输出
;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 ;比较符号标志位,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 0×80
编译 连接 运行如下:
jiayi:/mnt/3/asm # ./print_int
-10
jiayi:/mnt/3/asm #
要期中考试了,封装的事考完再折腾…
还有,应Jobru 童鞋的建议,代码背景颜色做了改动,不知顺眼否~

