加入库函数

加入一些实用的打印功能,这对我们的调试是大有帮助的,我们单独放到kliba.S文件中

 

.data
.global disp_str
disp_pos: .4byte  ((80 * 6 + 0) * 2) 
.text  
.globl disp_str,disp_int
.code32
/***************************************************************************
*                  void disp_str(char * info);
***************************************************************************/
disp_str:
	push	%ebp
	mov 	%esp, %ebp
	    	
	mov 	8(%ebp), %esi 	//字符串地址
	mov 	disp_pos, %edi 	//读出显示位置
	mov 	$0x0F, %ah 			//字符属性
	cld
	
disp_start:
	lodsb 								//将DS:ESI寻址的一个内存字节装入al
	test	 %al, %al				//两个操作数逻辑与运算,测试al是否为0
	jz  	 disp_end				//结果为0则设置ZF零标志为1,跳转到2,结束显示
	    	
	cmpb	 $0x0A, %al 		//是不是回车换行 al - 0xa = 0,则zf置1
	jz  	disp_enter			//是回车,zf=1,跳转
disp_char://显示一个字符
	movw    %ax, %gs:(%edi)
	add     $2, %edi
	//cmp   $((80 * 25 - 2) * 2), %edi//是否显示完一屏幕
	jmp     disp_start//显示下一字符

disp_enter://如果是enter,跳到下一行显示 ,每行显示80个字符,一个字符2字节      
	push	%eax				//eax入栈
	movl	%edi, %eax	//edi ---> eax
	movb	$160, %bl 	//160---> bl   80-char * 2byte=160
	divb	%bl					//160---> bl
	andl	$0xFF, %eax	//eax = eax & 0xff 当前所在行数
	incl	%eax 				//eax = eax + 1 Goto next line 
	movb	$160, %bl
	mulb	%bl					//eax = eax * 160
	movl	%eax, %edi	//eax---> edi
	popl	%eax
	jmp 	disp_start


disp_end:
	movl	%edi, disp_pos//保存显示位置
	popl	%ebp
	ret
	
	
	
/**-----------------------------------------------------------------
 * Print num in AL
 *------------------*/
DispAL:
        push    %ecx
        push    %edx
        push    %edi
        mov     (disp_pos), %edi
        mov     $0x0F, %ah
        mov     %al, %dl
        shrb    $4, %al
        mov     $2, %ecx

DispAL.begin:
        and     $0x0F, %al
        cmp     $9, %al
        ja      DispAL.1
        add     $'0', %al
        jmp     DispAL.2

DispAL.1:
        sub     $0x0A, %al
        add     $'A', %al

DispAL.2:
        mov     %ax, %gs:(%edi)
        add     $2, %edi
        mov     %dl, %al
        loop    DispAL.begin
        mov     %edi, (disp_pos)
        pop     %edi
        pop     %edx
        pop     %ecx
        ret

/***************************************************************************
*                  void disp_int(unsigned long num);
***************************************************************************/
disp_int:
        movl    4(%esp), %eax
        shr     $24, %eax
        call    DispAL

        movl    4(%esp), %eax
        shr     $16, %eax
        call    DispAL

        movl    4(%esp), %eax
        shr     $8, %eax
        call    DispAL

        movl    4(%esp), %eax
        call    DispAL

        movb    $0x07, %ah
        movb    $'h', %al
        pushl   %edi
        movl    (disp_pos), %edi
        movw    %ax, %gs:(%edi)
        addl    $4, %edi
        movl    %edi, (disp_pos)
        popl    %edi
        ret


相应的Makefile需要修改如下:

kliba.o:kliba.s
 $(AS) -o kliba.o -a kliba.s

system: head.o kliba.o main.o
 $(LD) $(LDFLAGS) -o system head.o kliba.o main.o

C中使用方法

void disp_str(char *info);
void disp_int(int num);
disp_str("How old are you?\n");
disp_int(0x12345678);

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值