A. python可以写软件么怎么写
22点24分准时推送,第一时间送达
编辑:技术君 | 来源:youerning
上一篇:
正文
前言
用 Python 写安卓 APP 肯定不是最好的选择,目前用Java和 kotlin 写的居多,但是肯定也是一个很偷懒的选择,而且实在不想学习 Java,再者,就编程而言已经会的就 Python与Golang(注:Python,Golang水平都一般),那么久Google了一下Python 写安卓的 APP 的可能性,还真行。
既然要写个APP,那么总得要有个想法吧。其实想做两个APP来着,一个是自己写着好玩的,一个是关于运维的。关于运维的APP,设计应该如下
可能长这样
然后设计应该是这样。
如果觉得可行的话,评论留言一下你觉得应该写进这个APP的运维常用命令吧^_^,笔者暂时想到的是top,free -m,df –h,uptime,iftop,iotop,如果有什么好的想法就狠狠的砸过来吧,笔者到时应该也会把这个写成一个项目放到github上,大家一起用嘛,开源才是王道,哈哈。
开发安卓APP
我们使用kivy开发安卓APP,Kivy是一套专门用于跨平台快速应用开发的开源框架,使用Python和Cython编写,对于多点触控有着非常良好的支持,不仅能让开发者快速完成简洁的交互原型设计,还支持代码重用和部署,绝对是一款颇让人惊艳的NUI框架。
因为跨平台的,所以只写一遍代码,就可以同时生成安卓及IOS的APP,很酷吧。
本文会带大家写一个Hello world并瞧一瞧 Python 版的2048的代码
kivy安装
环境说明:笔者在用的是Python2.7.10
这里仅介绍windows平台安装
所有平台参考: https://kivy.org/#download
更新pip,setuptools
python -m pip install --upgrade pip wheel setuptools
然后是安装所需要的依赖
python -m pip install docutils pygmentspypiwin32 kivy.deps.sdl2 kivy.deps.glew
kivy.deps.gstreamer --extra-index-url https://kivy.org/downloads/packages/simple/
值得注意的是,上面的安卓需要访问Google,所以请自备梯子,而且kivy.deps.gstreamer这个包比较大(95MB),可以单独本地安装,http://pan..com/s/1o7mlxNk
然后就是安装kivy了
python -m pip install kivy
至此,安装就已经完毕了,值得注意的是64位系统没有开启虚拟化支持,在导入kivy的时候会报错,如果是64位系统就设置一下机器的BIOS,开启虚拟化支持吧。
注:这里只是kivy的运行环境,这样我就能直接在windows机器上直接调试了,怎么将代码编译成APK文件我们会在后面讲到。
如果kivy在python中应该就能导入了。
按照世界惯例,我们”hello”一下吧。
新建一个.py文件
from kivy.app import Appfrom kivy.uix.button importButton
class TestApp(App):
def build(self):
return Button(text='Hello,kivy')
TestApp().run()
运行
然后会弹出一个框,大概如下,点击”hello,kivy”会变颜色
点击窗口并按“F1”会这个窗口的一些属性
然后我们回过头看一看代码。
##导入App,然后让TestApp这个类继承
from kivy.app import App##导入一个Button,运维有这个button,当你点击的时候才会有所反应
from kivy.uix.button
importButton
###定义类,名字必须是xxxAppclass TestApp(App):
###build一个Button
def build(self):
###返回一个Button,文字内容是“Hello,kivy”
return Button(text='Hello,kivy')
##运行,因为继承了App,所以才有的run这个方法TestApp().run()
上面就是我们的Hello了
在windows上运行当然没有什么太大的意义,怎么在安卓手机上运行才是我们想要的,
这时我们需要一个编译环境。
官方说明的环境,如下:
You’ll need:
A linux computer or a virtual machine
Java
Python 2.7 (not 2.6.)
Jinja2 (python mole)
Apache ant
android SDK
虽然官方提供了一个似乎还不错的虚拟机镜像,但是还是有很多内容需要翻出去,所以笔者在这里提供相对而言更加完善的镜像
下载地址:http://pan..com/s/1geyAY7x
注:virtualbox,vmware需自行下载
root密码:kivy
默认使用账户kivy,密码:kivy123
当然你也可以下载官方镜像,因为第一次编译需要去国外下一大堆东西,所以请自行去下载。
Virtual Machine
A Virtual Machine with Android SDK and NDK and all otherpre-requisites pre installed to ease apk generation:
Kivy Buildozer VM
Or select the Torrent
在笔者提供的镜像里,桌面上有一个dev_and,只要将上面写的代码,放入这个文件夹即可(当然也可以在其他目录,后面会讲到)。
在公众号Python人工智能技术后台回复“面试”,获取腾讯Python面试题和答案。
cd Desktop/dev_and/
初始化会在当前目录生成一个buildozer.spec文件 用于配置生成的apk相关信息
buildozer init
###修改buildozer.spec文件
vi buildozer.spec
至少修改下面三项
# (str) Title of your applicationtitle = helloworld
# (str) Package namepackage.name = helloapp
# (str) Package domain (needed for android/ios packaging)package.domain = youer.com
然后注释
# (str) Application versioning (method 1)#version.regex = __version__ = ['"](.*)['"]#version.filename = %(source.dir)s/main.py
下面这行改为非注释
version = 1.2.0
最后我们生成我们需要的apk文件
buildozer -v android debug
buildozer.spec更详细的相关参数配置参考:
http://buildozer.readthedocs.org/en/latest/specifications.html
buildozer命令会在当前文件夹创建一个bin,该文件夹里面有我们想要的apk文件
helloapp-1.2.0-debug.apk
helloapp-1.2.0-debug.apk
安装以后是这样:
话说在编译的时候可能出现空间不足的情况,根据虚拟机的不同(vmware或virtualbox)自行扩容吧。
最后我们来瞧瞧简易版Python开发的2048这个游戏的源代码。
代码:
https://github.com/mvasilkov/kb/tree/master/6_2048
先看效果图:
试玩了一下,还是蛮流畅的,有兴趣的可以下载玩一下
下载地址:http://pan..com/s/1eQZACDW
这个游戏代码虽然不长,但是还是蛮占篇幅的,所以简要的说明一下流程。
主要由三部分组成,一是素材,图片音频之类的文件,二是Python代码,三是kv文件,这个kv文件有点像 html 中的css。
Python代码的文件名一般命名为 main.py
然后一定有一个叫做 XXXApp 的类,并继承 App。
比如该类叫做GameApp,那么该目录下的kv文件则必须为Game,如上图所示,如果不是,那么kv文件中的一些设定就不会生效。
比如设定一个标签
Label:
id: time
text: 'xxxx'
font_size: 60
id为time,text文本内容为'xxxx',然后字体为60
好吧,点到为止吧,不过似乎什么都没点到~~~
你还有什么想要补充的吗?
你在看吗?一起成长
B. linux系统拷贝windows电脑共享的文件,用python怎么实现
装个samba 一般来说,安装samba后,有一个smb.conf(配置文件)的例子,修改一下就好了。 WINDOWS下的网上邻居使用是NetBIOS协议,LINUX下使用功能强大的SAMBA可以实现与WINDOWS机子共享。下面具体就我的理解具体说一下。 首先当然是你必须安装了SAMBA #apt-get install samba samba-common smbclient smbfs 其实使用SAMBA分成两个方面,一个是linux机子上的资源给WINDOWS机子浏览,再一个是使用LINUX 机子浏览WINDOWS 的网上邻居。现在假设使用WINDOWS的机子的IP是10.0.0.10,共享目录是music,用户名是:share,密码是:yeah;使用 LINUX机子的IP是:10.0.0.20 一 . 从LINUX上获取WINDOWS文件的基本方法(有3种方法) 1. smbmount---普通用户就可以使用的命令 挂载文件 #smbmount //10.0.0.10/music /home/user/music -o "username=share,password=yeah" 主意与下面的mount不一样的是-o后面一定要引号 卸载已经挂载的文件 #smbumount /home/user/music 2. mount---超级用户才有的权限,但效果与上面一样 挂载文件 #mount -t smbfs -o username=share,password=yeah //10.0.0.10/music /home/user/music 卸载文件 #umount /home/user/music 注:以上两个命令挂载要想显示中文,必须添加如下参数 codepage=cp936,iocharset=utf8(与linux机的本地环境一致,如是gb2312,这儿也要写成:iocharset=gb2312 ;codepage要与远程一致,是指定源代码文件的代码页---一个内>部表,操作系统用它将符号(字母、数字和标点)映射为字符编号。如932 代表日本汉字,950代表繁体中文字符集,说明一下就是codepage是cp936,而不是936,否则在有时显示汉字还是乱码。 3. 使用smbclient访问Windows资源 它是一个类似于ftp操作方式,通过远程操作的方式进行文件传递的软件。为了获得网络上可以访问的计算机列表,首先需要使用 smbclient来获得一个Windows计算机共享出来的资源,这需要使用-L参数访问IPC #smbclient -L 192.168.1.150 -N 或者机器名 #smbclient -L hit -N 如果不清楚一个Windows计算机的NetBIOS名字,可以使用nmblookup先来解析NetBIOS名字 #nmblookup hit (若浏览网上邻居用:#nmblookup -T "*") 当上面查到资源后,就可以用smbclient登陆了 #smbclient \\hit\music yeah -U share (其中yeah是密码,share是用户名) 执行smbclient命令成功后,进入smbclient环境,出现提示符:smb: >,然后就可以执行和ftp命令中相似的命令:cd, lcd, get ,mget ,put ,mput等,用法就跟FTP一样了。 注:要想使用smbclient来访问windows时,也需要使用UNC来标识Windows资源的位置。此时就需要了解 WindowsUNC在Unix>下进行表示的不同之处。不同之处在于Unix的shell下反斜线为特殊字符,它被定义为转义恢复字符,表示将一些转义字符恢复为其本身字符的意义。因此必须使用两个反斜线才能等同于一个反斜线。因此一个UNC实际使用时应使用双倍的反斜线。 若想使用基于图形的客户端:感觉比较好用的是tksmb和smb4k(KDE) 若只是以上使用不用配置/etc/samba/smb.conf,也不用启动 samba 服务,甚至可以不装samba程序 二. WINDOWS机子访问在LINUX上的资源 需要使用两个进程:nmbd smbd, 前者nmbd是提供WINDOWS浏览,后者smbd是针对WINDOWS浏览后的登陆等服务。 首先需要说明的是,当samba 还没有添加用户时,WINDOWS机子是登陆不上来的,所以第一步就是添加用户: # smbpasswd -a myfirst 需要说明的是这个用户必须是系统用户,否则回提示 Failed to initialise SAM_ACCOUNT for user myfirst. Does this user exist in the UNIX password database ? Failed to modify password entry for user myfirst 当然可以对用户进行映射,见后面说明。 接着就简单了,就是配置/etc/samba/smb.conf,见下面一个配置以及相应说明,拷贝后您只需要稍稍修改一些你自己的信息就可以使用了(参考了前人的说明) /etc/samba/smb.conf文件 ## /etc/samba/smb.conf配置文件有三个重要的节:[global],[homes],[public] #Global (全局)参数,该部分设置整个系统的规则,定义了一些公共变量。 [global] netbios >#定义Windows系统“网上邻居”中所见的机器名。 workgroup = workgroup #定义主机所在网络上所属的NT域名或者工作组名称 server string = FunField #对主机的说明信息,缺省是:Samba Server hosts allow = 192.168.1. 192.168.3. #它允许设置哪些机器可以访问samba服务器 guest account = nobody invalid users = root #定义smb用户名称。 security = user #定义访问权限。访问权限由低到高有三种:share、user和server。其中share安全级别最低,user模式要求连接时输入用户名和口令 encrypt passwords = true #设置是否需要加密口令。因为Windows系列默认采用加密口令传输,而Linux默认采用非加密口令传输,为保证smb网络用户的正常登录,在user安全级下设置为加密,在share 安全级下可不设。 smb passwd file = /etc/samba/smbpasswd #由命令cat /etc/passwd mksmbpasswd.sh > /etc/samba/smbpasswd产生。 interfaces = 192.168.1.50/24 #配置smb服务所使用的网卡IP以及子网掩码,如果有两个以上网卡,要全部列出。 name resolve order = host dns bcast #设定smb服务时,从机器netbios名称到IP地址的解析方式,默认顺序为host lmhosts wins bcast。如果局域网内有DNS,可设置为host dns bcast。 wins support = no #设置是否有wins支持。 public = yes #为yes时,“网上邻居”中可见该资源,否则不可见。 browseable = yes #为yes时,“网上邻居”中可见该资源,否则不可见。 #printing = bsd # 指定Linux使用哪个打印机守护进程(bsd、sysv、hpux、aix、qnx、plp),同时向samba说明命令lpr和lpq的缺省值。 #printcap ># 定义了打印配置文件所处的位置。 load printers = no # 表明是否加载printcap 定义的所有打印机以供浏览。 log file = /var/log/samba/log.%m # 定义日志文件 max log 'size' = 1000 #日志文件最大1000k (单位是KB) username map = /etc/samba/smbuser #允许管理员指定一个映射文件,该文件包含了在客户机和服务器之间进行用户映射的信息。 用户映射经常在windows 和linux 主机间进行。 两个系统拥有不同的用户账号,用户映射的目的是将不同的用户映射成为一个用户,便于共享文件。 #*********************************************************************# [homes] #该部分通常定义了Linux机器上共享的目录资源,其名字可以由用户确定。段中的设置控制了每一个用户目录的共享权限。 comment = Home Directories #设定在浏览本机资源时,出现在指定资源旁边的字符串。 browseable = yes #控制一项服务是否能够出现在网上邻居中,no意味着这个目录将在浏览时显示为要验证的用户名称,yes则显示 homes 和要验证的用户名称的共享目录。 writable = yes #控制是否允许通过验证的用户对主目录有写入的权限,但最终取决于该目录的 Unix 权限。无论 Unix 的权限怎样, 设置 writable = no 后, 主目录只能是只读的。 create mask = 0700 directory mask = 0700 #若上面是可写的,则设置写文件和目录时的属性 #******************************************************************# [public] #用来指定某一特定用户组或者用户拥有访问权限的目录配置分,配置共享目录部分 comment = Public Stuff # 说明部分 path = /home/samba #共享的Linux目录 writable = no #写权限 printable = no #打印权限 用于用户映射的文件/etc/samba/smbuser # smb.conf中全局参数 “username map” 指定的映射文件 root = admin administrator #Map Windows admin to root hawk = girl #Map the member of girl to hawk snake = boy # 等号左边是单独的Linux账号,等号右边是要映射的账号列表。服务器逐行分析映射文件,如果提供的账号和某行有右侧列表中的账号匹配,就把它替换为等号左边的账号。
C. 利用python写一段读取电脑配置信息的程序
主要利用python的wmi模块,提供非常多的信息。
importwmi
defsys_version():
c=wmi.WMI()
#操作系统版本,版本号,32位/64位
print(' OS:')
sys=c.Win32_OperatingSystem()[0]
print(sys.Caption,sys.BuildNumber,sys.OSArchitecture)
#CPU类型CPU内存
print(' CPU:')
processor=c.Win32_Processor()[0]
print(processor.Name.strip())
Memory=c.Win32_PhysicalMemory()[0]
print(int(Memory.Capacity)//1048576,'M')
#硬盘名称,硬盘剩余空间,硬盘总大小
print(' DISK:')
fordiskinc.Win32_LogicalDisk(DriveType=3):
print(disk.Caption,'free:',int(disk.FreeSpace)//1048576,'M ','All:',int(disk.Size)//1048576,'M')
#获取MAC和IP地址
print(' IP:')
forinterfaceinc.Win32_NetworkAdapterConfiguration(IPEnabled=1):
print("MAC:%s"%interface.MACAddress)
forip_addressininterface.IPAddress:
print(" IP:%s"%ip_address)
#BIOS版本生产厂家释放日期
print(' BIOS:')
bios=c.Win32_BIOS()[0]
print(bios.Version)
print(bios.Manufacturer)
print(bios.ReleaseDate)
sys_version()
显示:
OS:
MicrosoftWindows10专业版1713464位
CPU:
Intel(R)Core(TM)[email protected]
8192M
DISK:
C:free:34165M All:120825M
D:free:265648M All:390777M
E:free:35669M All:204796M
F:free:5814M All:28163M
G:free:328650M All:329999M
IP:
MAC:00:50:56:C0:00:01
IP:192.168.182.1
IP:fe80::e0fb:efd8:ecb0:77f4
MAC:00:50:56:C0:00:08
IP:192.168.213.1
IP:fe80::8da1:ce76:dae:bd48
MAC:54:E1:AD:77:57:AB
IP:192.168.199.105
IP:fe80::aca8:4e6f:46e7:ef4a
BIOS:
LENOVO-1
LENOVO
20170518000000.000000+000
D. python可以改写MBR吗
肯定是可以的,你可以尝试使用python的c扩展
一, 实验内容
改写bootsect.s和setup.s, 完成如下主要功能:
1, bootsect.s能够在屏幕上打印一段提示信息"XXX is booting...", 其中XXX是你给自己的操作系统起的名字,例如LZJos、Sunix等.
2, bootsect.s能够完成setup.s的载入, 并跳转到setup.s开始地址执行.
3, setup.s能够像屏幕输出一行信息 "Now we are in SETUP"
4, setup.s能获取至少一个基本的硬件参数(如内存参数、显卡参数、硬盘参数等),将其存放在内存的特定地址,并输出到屏幕上。
setup.s不再加载linux内核, 保持上述信息显示到屏幕上即可
二, 实验步骤
1, 完成bootsect的屏幕输出功能
由于不需要加载linux内核,所以就不需要原始的linux代码那么复杂,比如: 将bootsect自身移动到0x90000处等操作,可以忽略的。
要显示字符串,那么字符串显示到屏幕的哪里呢?当然是当前光标的位置了!所以第一步就要先读取光标的位置,这可以利用10号中断的3号子程序来完成。要显示字符串,可以利用10号功能的13号子程序来完成,需要注意的是一定要边显示字符边移动光标,最终的光标要移动到字符串的末尾处。最后要注意用0xAA55来标记引导扇区。代码如下:
! 文件:bootsect.s
entry _start
_start:
! 首先利用10号中断的3号功能来读取光标位置
mov ah,#0x03
xor bh,bh
int 0x10
! 再利用10号中断的13号功能显示字符串
mov cx,#50 ! 加上回车和换行,字符串一共包含50个字符,所以设置cx为50
mov bx,#0x0007
mov bp,#msg1
mov ax,#0x07c0
mov es,ax ! es:bp=显示字符串的地址
mov ax,#0x1301
int 0x10
Inf_loop:
jmp Inf_loop ! 无限循环
! msg1处放置要显示的字符串
msg1:
.byte 13,10 ! 换行+回车
.ascii "AXF OS is booting, my name is Aixiangfei ..."
.byte 13,10,13,10 ! 两对换行+回车
! 下面是启动盘具有有效引导扇区的标志. 仅供BIOS中的程序加载扇区时识别使用。
! 它必须位于引导扇区的最后两个字节中.
.org 510
boot_flag:
.word 0xAA55 ! 引导扇区的标记就是0XAA55
编译和运行: 进入~/oslab/linux-0.11/boot/目录,编译并连接:
as86 -0 -a -o bootsect.o bootsect.s
ld86 -0 -s -o bootsect bootsect.o
参数说明:-0(注意:这是数字0,不是字母O)表示生成8086的16位目标程序,-a表示生成与GNU as和ld部分兼容的代码,-s告诉链接器ld86去除最后生成的可执行文件中的符号信息。
如果这两个命令没有任何输出,说明编译与链接都通过了。需要留意的生成的bootsect的大小是544字节,而引导程序必须要正好占用一个磁盘扇区,即512个字节。造成多了32个字节的原因是ld86产生的是Minix可执行文件格式,这样的可执行文件处理文本段、数据段等部分以外,还包括一个Minix可执行文件头部。所以最后必须要把这多余的32个字节删掉,可以用linux自带的工具dd来完成:
dd bs=1 if=bootsect of=Image skip=32
去掉这32个字节后,将生成的文件拷贝到linux-0.11目录下,并一定要命名为“Image”(注意大小写)。然后就可以run了
程序有可能需要不断地修改调试,为了方便,可以将上述的一系列操作写道一个shell脚本文件 cbootsect.sh 中:
#!/bin/sh
as86 -0 -a -o bootsect.o bootsect.s
ld86 -0 -s -o bootsect bootsect.o
dd bs=1 if=bootsect of=Image skip=32
cp Image ../
../../run
运行结果:
2, setup的载入
首先要确定setup是在磁盘的0磁道2扇区,linux 0.11中的setup占了4个扇区,而我们最后要写的setup显然没有那么复杂,所以可以只用1个扇区就可以了。另外,由于bootsect位于0x7c00处,占用512个字节,所以可以将setup载入到0x7e00处。要想从磁盘中载入数据到内存,可以利用BIOS提供的13号中断轻松完成。最后就直接用jumi指令跳转到0x7e00处即可。对前面的bootsect.s扩展之后的完整代码如下:
! 文件:bootsect.s
SETUPLEN = 1
SETUPSEG = 0x07e0
entry _start
_start:
! 首先利用10号中断的3号功能来读取光标位置
mov ah,#0x03
xor bh,bh
int 0x10
! 再利用10号中断的13号功能显示字符串
mov cx,#50 ! 加上回车和换行,字符串一共包含50个字符,所以设置cx为50
mov bx,#0x0007
mov bp,#msg1
mov ax,#0x07c0
mov es,ax ! es:bp=显示字符串的地址
mov ax,#0x1301
int 0x10
load_setup:
mov dx,#0x0000 ! 设置驱动器和磁头(drive 0, head 0): 软盘0磁头
mov cx,#0x0002 ! 设置扇区号和磁道(sector 2, track 0):0磁头、0磁道、2扇区
mov bx,#0x0200 ! 设置读入的内存地址:BOOTSEG+address = 512,偏移512字节
mov ax,#0x0200+SETUPLEN ! 设置读入的扇区个数(service 2, nr of sectors),
! SETUPLEN是读入的扇区个数,Linux 0.11设置的是4,
! 我们不需要那么多,我们设置为1
int 0x13 ! 应用0x13号BIOS中断读入1个setup.s扇区
jnc ok_load_setup ! 读入成功,跳转到ok_load_setup: ok - continue
mov dx,#0x0000 ! 软驱、软盘有问题才会执行到这里
mov ax,#0x0000 ! 否则复位软驱
int 0x13
j load_setup ! 重新循环,再次尝试读取
ok_load_setup:
jmpi 0,SETUPSEG
! msg1处放置要显示的字符串
msg1:
.byte 13,10 ! 换行+回车
.ascii "AXF OS is booting, my name is Aixiangfei ..."
.byte 13,10,13,10 ! 两对换行+回车
! 下面是启动盘具有有效引导扇区的标志. 仅供BIOS中的程序加载扇区时识别使用。
! 它必须位于引导扇区的最后两个字节中.
.org 510
boot_flag:
.word 0xAA55 ! 引导扇区的标记就是0XAA55
3, 完成setup的屏幕输出功能
这个很简单,跟bootsect是一样的。代码如下:
! 文件:setup.s
entry _start
_start:
! 首先利用10号中断的3号功能来读取光标位置
mov ah,#0x03
xor bh,bh
int 0x10
! 再利用10号中断的13号功能显示字符串
mov cx,#26
mov bx,#0x0007
mov bp,#msg
mov ax,cs
mov es,ax
mov ax,#0x1301
int 0x10
Inf_loop:
jmp Inf_loop ! 无限循环
msg:
.byte 13,10
.ascii "Now we are in SETUP."
.byte 13,10,13,10
.org 510
boot_flag:
.word 0xAA55
编译和与运行:现在有两个文件都要编译、链接。一个个手工编译,效率低下,所以借助Makefile是最佳方式。linux 0.11中Makefile文件已经帮我们把这件事做好了。进入liux-0.11目录后,使用命令:
$ make BootImage
但是我们发现竟然出现了错误:
原因:这是因为make根据Makefile的指引执行了tools/build.c,它是为生成整个内核的镜像文件而设计的,没考虑我们只需要bootsect.s和setup.s的情况。build.c从命令行参数得到bootsect、setup和system内核的文件名,将三者做简单的整理后一起写入Image。其中system是第三个参数(argv[3])。当“make all”或者“makeall”的时候,这个参数传过来的是正确的文件名,build.c会打开它,将内容写入Image。而“make BootImage”时,传过来的是字符串"none"。所以,修改build.c的思路就是当argv[3]是"none"的时候,只写bootsect和setup,忽略所有与system有关的工作,或者在该写system的位置都写上“0”。
修改build.c文件很简单,只需要把第178到183这几行代码删除即可!
// if ((id=open(argv[3],O_RDONLY,0))<0)
// die("Unable to open 'system'");
// if (read(id,buf,GCC_HEADER) != GCC_HEADER)
// die("Unable to read header of 'system'");
// if (((long *) buf)[5] != 0)
// die("Non-GCC header of 'system'");
run
4, 读取硬件参数
这个部分是最复杂的了。需要打印的硬件信息有:光标位置,内存大小,磁盘的柱面数,磁头数,每磁道的扇区数。在这个实验中,这些参数的信息可以保存在内存中的任意位置,在linux 0.11中,这些参数信息是被保存到了0x90000处,所以不妨跟linux 0.11一样。
(1)获取硬件参数
获得光标位置信息,这个很简单,只需要调用13号中断的3号子程序就可以得到,前面已经用过了的。
获得内存大小,可以调用用15号中断的88号子程序得到,也很简单。
与磁盘相关的信息稍微复杂一点,这些信息被保存在0x0000:0x0104地址处的16个字节的中,这16个字节的信息叫做“磁盘参数表”。所以获得磁盘信息的方法就是复制数据。
(2)数字转字符
现在已经将这些硬件参数取出来放在了0x90000处,接下来的工作是将这些参数显示在屏幕上。这些参数都是一些无符号整数,所以需要做的主要工作是用汇编程序在屏幕上将这些整数用16进制的形式显示出来。
因为十六进制与二进制有很好的对应关系(每4位二进制数和1位十六进制数存在一一对应关系),显示时只需将原二进制数每4位划成一组,按组求对应的ASCII码送显示器即可。ASCII码与十六进制数字的对应关系为:0x30~0x39对应数字0~9,0x41~0x46对应数字a~f。从数字9到a,其ASCII码间隔了7h,这一点在转换时要特别注意。为使一个十六进制数能按高位到低位依次显示,实际编程中,需对bx中的数每次循环左移一组(4位二进制),然后屏蔽掉当前高12位,对当前余下的4位(即1位十六进制数)求其ASCII码,要判断它是0~9还是a~f,是前者则加0x30得对应的ASCII码,后者则要加0x37才行,最后送显示器输出。以上步骤重复4次,就可以完成bx中数以4位十六进制的形式显示出来。
因为在输出的时候需要调用多次,所以最好把这个功能写成一个函数print_bx,方便使用。既然要用到函数,故一定要先设置好栈。为了方便,还可以写一个函数print_nl实现换行的功能。
INITSEG = 0x9000
entry _start
_start:
! 在显示字符串之前必须先获取当前光标的位置,这样就可以把字符串显示到当前光标处了
mov ah,#0x03
xor bh,bh
int 0x10
! 利用10号中断的13号功能打印字符串"Now we are in SETUP."
mov cx,#26
mov bx,#0x0007
mov bp,#msg1
mov ax,cs
mov es,ax
mov ax,#0x1301
int 0x10
! 下面开始读取一些硬件参数
! 读入光标位置信息,保存到0x90000处
mov ax,#INITSEG
mov ds,ax
mov ah,#0x03
xor bh,bh
int 0x10
mov [0],ds
! 读入内存大小位置信息,保存到0x90002处
mov ah,#0x88
int 0x15
mov [2],ax
! 从0x41处拷贝16个字节(磁盘参数表)到0x90004处
mov ax,#0x0000
mov ds,ax
lds si,[4*0x41]
mov ax,#INITSEG
mov es,ax
mov di,#0x0004
mov cx,#0x10
rep ! 重复16次
movsb
! 先打印光标位置
! 打印字符串之前要先读取光标位置,将字符串打印到当前光标处
mov ah,#0x03
xor bh,bh
int 0x10
! 打印字符串 "Cursor POS:"
mov cx,#11
mov bx,#0x0007
mov ax,cs
mov es,ax
mov bp,#msg2
mov ax,#0x1301
int 0x10
! 调用打印函数,打印光标位置
mov ax,#0x9000
mov ds,ax
mov dx,0x0
call print_hex
call print_nl
! 打印内存大小
! 打印字符串"Memory SIZE:"
mov ah,#0x03
xor bh,bh
int 0x10 ! 读取光标位置
mov cx,#12
mov bx,#0x0007
mov ax,cs
mov es,ax
mov bp,#msg3
mov ax,#0x1301
int 0x10
! 调用打印函数,打印内存大小信息
mov ax,#0x9000
mov ds,ax
mov dx,0x2
call print_hex
! 打印字符串"KB"
mov ah,#0x03
xor bh,bh
int 0x10 ! 读取光标位置
mov cx,#2
mov bx,#0x0007
mov ax,cs
mov es,ax
mov bp,#msg4
mov ax,#0x1301
int 0x10
call print_nl
!打印柱面数
! 打印字符串"Cyls"
mov ah,#0x03
xor bh,bh
int 0x10 ! 读取光标位置
mov cx,#5
mov bx,#0x0007
mov ax,cs
mov es,ax
mov bp,#msg5
mov ax,#0x1301
int 0x10
! 调用打印函数打印磁盘柱面数
mov ax,#0x9000
mov ds,ax
mov dx,0x4
call print_hex
call print_nl
! 打印磁头数
! 打印字符串"Heads:"
mov ah,#0x03
xor bh,bh
int 0x10 ! 读取光标位置
mov cx,#6
mov bx,#0x0007
mov ax,cs
mov es,ax
mov bp,#msg6
mov ax,#0x1301
int 0x10
! 调用打印函数打印磁盘磁头数
mov ax,#0x9000
mov ds,ax
mov dx,0x6
call print_hex
call print_nl
! 打印每磁道扇区数
! 打印字符串"sectors"
mov ah,#0x03
xor bh,bh
int 0x10 ! 读取光标位置
mov cx,#8
mov bx,#0x0007
mov ax,cs
mov es,ax
mov bp,#msg7
mov ax,#0x1301
int 0x10
! 调用打印函数打印扇区数
mov ax,#0x9000
mov ds,ax
mov dx,0x12
call print_hex
call print_nl
Inf_loop:
jmp Inf_loop ! 无限循环
! print_hex函数:将一个数字转换为ascii码字符,并打印到屏幕上
! 参数值:dx
! 返回值:无
print_hex:
mov cx,#4 ! 要打印4个十六进制数字,故循环4次
print_digit:
rol dx,#4 ! 循环以使低4比特用上 !! 取dx的高4比特移到低4比特处
mov ax,#0xe0f ! ah = 请求的功能值,al = 半字节(4个比特)掩码
and al,dl ! 取dl的低4比特值
add al,#0x30 ! 给al数字加上十六进制0x30
cmp al,#0x3a
jl outp ! 如果是一个不大于十的数字
add al,#0x07 ! 如果是a~f,要多加7
outp:
int 0x10
loop print_digit ! 用loop重复4次
ret
! 打印回车换行
print_nl:
mov ax,#0xe0d
int 0x10
mov al,#0xa
int 0x10
ret
msg1:
.byte 13,10
.ascii "Now we are in SETUP."
.byte 13,10,13,10
msg2:
.ascii "Cursor POS:"
msg3:
.ascii "Memory SIZE:"
msg4:
.ascii "KB"
msg5:
.ascii "Cyls:"
msg6:
.ascii "Heads:"
msg7:
.ascii "Sectors:"
.org 510
boot_flag:
.word 0xAA55
运行结果:
E. 怎样查看python安装路径
方法如下:
一、linux查看python安装位置。
有时我们需要查看python的安装位置,好安装第三方库,linux可以先python进入python cmd,然后输入【import sys】【print sys.path】,即可打印所有python路径。
二、想要查看ubuntu中安装的python路径。
方法一:whereis python
方法二:which python
五、sys.executable是当前Python解释器(或者其他Python实现)的路径去掉后面一个路径分隔符(Windows下是'')后的部分即可>>> import sys>>> path = sys.executable>>> print pathC:Python25pythonw.exe>>> folder = path[ 0 : path.rfind( os.sep ) ]>>> print folderC:Python25>>>。