lcall(调用门)和0x80(中断门)触发系统调用区别

你想要用“手动中断(int 指令)”的方式触发系统调用,而不是用 lcall(调用门),这是完全可行的,而且在早期 Linux(如 int 0x80)中就是这么做的。

下面是你实现这类机制所需要的完整步骤,包括用户态和内核态的设计。


✅ 一、用户态:使用 int 指令触发中断

你可以写一个系统调用封装函数,比如:

static inline int sys_call(syscall_args_t *args) {
   
   
    int ret;
    __asm__ __volatile__ (
        "int $0x80\n"
        :
``` LJMP MAIN ORG 000BH LJMP TIMER0_ISR PATTERN_TABLE: DB 0x01,0x02,0x04,0x08,0x10,0x20,0x40,0x80 DB 0x80,0x40,0x20,0x10,0x08,0x04,0x02,0x01 DB 0x81,0x42,0x24,0x18,0x18,0x24,0x42,0x81 DB 0xAA,0x55,0xAA,0x55,0xAA,0x55,0xAA,0x55 DB 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF DB 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 DB 0xFF,0x00,0xFF,0x00,0xFF,0x00,0xFF,0x00 DB 0x18,0x3C,0x7E,0xFF,0xFF,0x7E,0x3C,0x18 DB 0x0C,0x1E,0x3E,0x7C,0x7C,0x3E,0x1E,0x0C DB 0x08,0x0C,0x0E,0xFF,0xFF,0x0E,0x0C,0x08 DB 0x3C,0x42,0x81,0x81,0x81,0x81,0x42,0x3C DB 0x00,0x00,0x18,0x3C,0x3C,0x18,0x00,0x00 DB 0x18,0x18,0x18,0xFF,0xFF,0x18,0x18,0x18 DB 0x01,0x03,0x07,0x0F,0x1F,0x3F,0x7F,0xFF DB 0xFF,0x7F,0x3F,0x1F,0x0F,0x07,0x03,0x01 DB 0x00,0x20,0x60,0x40,0x40,0x60,0x20,0x00 DB 0xE0,0x80,0x80,0x80,0x80,0x80,0x80,0x80 DB 0x3C,0x42,0x81,0x81,0x81,0x81,0x42,0x3C DB 0x08,0x18,0x28,0x08,0x08,0x08,0x08,0x1C DB 0x18,0x24,0x42,0x7E,0x42,0x42,0x42,0x42 DB 0x3C,0x42,0x95,0xA1,0xA1,0x95,0x42,0x3C DB 0xFF,0x81,0x81,0x81,0x81,0x81,0x81,0xFF DB 0x3C,0x42,0x99,0xA5,0xA5,0x99,0x42,0x3C DB 0x08,0x0C,0x0E,0xFF,0xFF,0x0E,0x0C,0x08 DB 0x10,0x30,0x70,0xFF,0xFF,0x70,0x30,0x10 DB 0x80,0xC0,0xE0,0xF0,0xF8,0xFC,0xFE,0xFF DB 0xFF,0xFE,0xFC,0xF8,0xF0,0xE0,0xC0,0x80 DB 0x24,0x5A,0x24,0x5A,0x81,0x5A,0x24,0x5A DB 0x99,0x5A,0x3C,0xE7,0xE7,0x3C,0x5A,0x99 DB 0xAA,0x55,0xAA,0x55,0xAA,0x55,0xAA,0x55 DB 0x00,0x00,0x18,0x24,0x24,0x18,0x00,0x00 DB 0x00,0x18,0x24,0x42,0x42,0x24,0x18,0x00 DB 0x81,0x42,0x24,0x18,0x18,0x24,0x42,0x81 DB 0x01,0x02,0x04,0x08,0x01,0x02,0x04,0x08 DB 0x08,0x04,0x02,0x01,0x08,0x04,0x02,0x01 DB 0x7E,0x40,0x40,0x7E,0x02,0x02,0x02,0x7E DB 0x7E,0x41,0x41,0x7E,0x41,0x41,0x41,0x7E DB 0x3E,0x41,0x80,0x80,0x80,0x80,0x41,0x3E DB 0x7C,0x42,0x41,0x41,0x41,0x41,0x42,0x7C DB 0x7F,0x40,0x40,0x7F,0x40,0x40,0x40,0x7F DB 0x08,0x14,0x22,0x7F,0x7F,0x22,0x14,0x08 DB 0xFF,0x81,0x42,0x24,0x18,0x24,0x42,0xFF DB 0x03,0x07,0x0F,0x1F,0x1E,0x1C,0x18,0x10 DB 0x1C,0x22,0x41,0xFF,0x9D,0x9D,0x9D,0xFF DB 0x3E,0x22,0x7F,0x41,0x41,0x41,0x41,0x7F DB 0x00,0x00,0x18,0x24,0x5A,0x81,0x42,0x24 DB 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80 DB 0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x40 DB 0x01,0x02,0x04,0x08,0x01,0x02,0x04,0x08 DB 0x08,0x04,0x02,0x01,0x08,0x04,0x02,0x01 DB 0x7E,0x40,0x40,0x7E,0x02,0x02,0x02,0x7E DB 0x7E,0x41,0x41,0x7E,0x41,0x41,0x41,0x7E DB 0x3E,0x41,0x80,0x80,0x80,0x80,0x41,0x3E DB 0x7C,0x42,0x41,0x41,0x41,0x41,0x42,0x7C DB 0x7F,0x40,0x40,0x7F,0x40,0x40,0x40,0x7F DB 0x08,0x14,0x22,0x7F,0x7F,0x22,0x14,0x08 DB 0xFF,0x81,0x42,0x24,0x18,0x24,0x42,0xFF DB 0x03,0x07,0x0F,0x1F,0x1E,0x1C,0x18,0x10 DB 0x1C,0x22,0x41,0xFF,0x9D,0x9D,0x9D,0xFF DB 0x3E,0x22,0x7F,0x41,0x41,0x41,0x41,0x7F DB 0x00,0x00,0x18,0x24,0x5A,0x81,0x42,0x24 DB 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80 DB 0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x40 MAIN: MOV SP, #60H MOV R0, #00H MOV R2, #100 MOV TMOD, #01H MOV TH0, #0FCH MOV TL0, #66H SETB TR0 SETB ET0 SETB EA MAIN_LOOP: LCALL DISPLAY_PATTERN SJMP MAIN_LOOP DISPLAY_PATTERN: MOV DPTR, #PATTERN_TABLE MOV A, R0 MOV B, #8 MUL AB ADD A, DPL MOV DPL, A MOV A, B ADDC A, DPH MOV DPH, A MOV R1, #8 DISPLAY_LOOP: CLR A MOVC A, @A+DPTR MOV P0, A INC DPTR MOV P0, #00H LCALL DELAY_1US DJNZ R1, DISPLAY_LOOP RET TIMER0_ISR: PUSH PSW PUSH ACC MOV TH0, #0FCH MOV TL0, #66H DJNZ R2, TIMER_EXIT MOV R2, #100 INC R0 CJNE R0, #64, TIMER_EXIT MOV R0, #00H TIMER_EXIT: POP ACC POP PSW RETI DELAY_1US: MOV R3, #2 DELAY_LOOP: NOP DJNZ R3, DELAY_LOOP RET END```为什么只显示前50个图
03-17
#include<reg51.h> #include<intrins.h> #define uchar unsigned char #define uint unsigned int #define data1 P0 #define data2 P2 sbit s1=P3^6; sbit s2=P3^7; bit fangxiang; uint alt=0,net=0,sl=66; bit mode; uchar code tab[]={ // 0x20,0x08,0x24,0x10,0x22,0x60,0x21,0x80,0x26,0x41,0x39,0x32,0x02,0x04,0x0C,0x18, 0xF0,0x60,0x13,0x80,0x10,0x60,0x10,0x18,0x14,0x04,0x18,0x02,0x00,0x01,0x00,0x00,/*"欢",2*/ 0x02,0x00,0x02,0x02,0x42,0x04,0x33,0xF8,0x00,0x04,0x00,0x02,0x3F,0xF2,0x20,0x22, 0x40,0x42,0x00,0x02,0x3F,0xFE,0x20,0x42,0x20,0x22,0x3F,0xC2,0x00,0x02,0x00,0x00,/*"迎",3*/ 0x00,0x80,0x01,0x00,0x06,0x00,0x1F,0xFF,0xE0,0x00,0x02,0x08,0x04,0x30,0x18,0xC0, 0xF0,0x02,0x10,0x01,0x13,0xFE,0x10,0x00,0x10,0x80,0x14,0x60,0x18,0x18,0x00,0x00,/*"你",4*/ }; void delay(uint z) //延时子函数 { uchar x; for(;z>0;z--) for(x=110;x>0;x--); } void xianshi() //显示 { uchar aa,i; for(i=0;i<16;i++) { P1=i; //列扫描 data1=tab[net+aa]; //取出上8行数据输出 aa++; data2=tab[net+aa]; //取出下8行数据输出 aa++; delay(5); //延时 data1=0; //清屏 data2=0; //清屏 P1=0x00; //消除余辉 if(aa>30) aa=0; //字模地址 } } void main() //主函数 { ET1=1; //使能定时器0 EA=1; //开启总中断 TR1=1; //开始计数 while(1) //无限循环 { xianshi(); //显示 if(s1==0) //检测按键 { delay(30); //延时消抖 TR1=~TR1; //按下暂停 ,暂按继续 while(!s1)xianshi(); delay(30); } if(s2==0) //检测按键 { delay(30); //延时消抖 fangxiang=~fangxiang; //方向取反 while(!s2)xianshi(); delay(30); } } } void timer1() interrupt 3 { alt++; if(alt==10) //到一定的时间加以实现左移 { alt=0; if(fangxiang==0) //如果是正向 正向移动 { net=net+2; if(net>sl) //字移动数量 net=0; } else //否则反向移动 { net=net-2; if(net<2) net=sl; //字移动数量 } } } 转换为汇编语言,但原程序功能一致
最新发布
06-07
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值