关于汇编的几个问题
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了关于汇编的几个问题相关的知识,希望对你有一定的参考价值。
有以下几个问题,希望高手能一一解答
1、系统是用汇编编写的么
2、汇编可不可以写可视化的程序,或者3D的
3、汇编编译出来的obj文件必须经过连接才可以执行么
4、obj可以连接成任意可执行文件,实现跨平台么
5、汇编的程序可不可以在没有操作系统的情况下运行,如果可以,怎么运行
就这些了,希望高手解答,能多少是多少。。
2:只要你问出这个问题,我想你是可能是没有弄清楚汇编的概念,这么跟你说吧, 你在windows上面玩的所有东西,包括你玩的超大型游戏,都可以用汇编来写,虽然实际上这不现实,也没人会这么做。但一个DOS格式文件或者一个WIN32下的PE(exe)文件内部 都是二进制内容是可以反汇编的,里面说白了存储的都是汇编代码(实际上是机器码,但机器码跟汇编代码是一一对应的)
可视化编程吧,汇编是不能实现所见即所得的那种可视化编程的,但是资源还是可以用资源编辑器编写,在链接的时候连接进去。
对于编写可视化程序给你一段代码:
.386
.model flat,stdcall
option casemap:none
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
; Include 文件定义
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
include windows.inc
include user32.inc
includelib user32.lib
include kernel32.inc
includelib kernel32.lib
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
; 数据段
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
.data
szCaption db 'A MessageBox !',0
szText db 'Hello, World !',0
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
; 代码段
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
.code
start:
invoke MessageBox,NULL,offset szText,offset szCaption,MB_OK
invoke ExitProcess,NULL
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
end start
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
用下列命令进行编译和链接:
; ml /c /coff Hello.asm
; Link /subsystem:windows Hello.obj
(win32汇编编译环境你可以到网上搜索masm32)
汇编在windows平台下也能调用api。3D效果也都是DX什么这些东西的API 调用出来的!
一句话:高级(其他任何)语言能做的汇编都能做,高级(其他任何)语言不能做的,只有计算机能完成的汇编都能做(比如操作系统引导部分)
3:汇编编译出来的文件obj文件在win32平台下面一般都是COFF文件格式,coff格式百度上有详细介绍
COFF文件跟EXE文件其实很像了,对于特殊的编译选项,比如在写操作系统引导的时候你不需要生成额外的信息,你要的是在目标文件每一个字节处的机器码,即你要精准定位每一行代码 都对应目标文件的位置。这个时候就不需要连接,汇编出来的文件直接裸机就能运行
4:
obj文件在linux上和windows上 都是采用coff格式的。假如linux不用系统调用 windows不用windows api也许 这两个系统的coff文件就完全一样了!不过 在调用系统接口的时候 linux用的是系统调用,windows用的是windows api,即使coff文件格式一样,也不能跨平台,很抱歉!
5:汇编程序能在没有操作系统的情况下运行
你需要一个nasm编译器(貌似现在也只有这个编译器能按指令一行一行编译到目标文件中)
汇编代码如下:
org 07c00h ; 告诉编译器程序加载到7c00处
mov ax, cs
mov ds, ax
mov es, ax
call DispStr ; 调用显示字符串例程
jmp $ ; 无限循环
DispStr:
mov ax, BootMessage
mov bp, ax ; ES:BP = 串地址
mov cx, 22 ; CX = 串长度
mov ax, 01301h ; AH = 13, AL = 01h
mov bx, 000ch ; 页号为0(BH = 0) 黑底红字(BL = 0Ch,高亮)
mov dl, 0
int 10h ; 10h 号中断
ret
BootMessage: db "Powerd By HuangLiuyou"
times 510-($-$$) db 0 ; 填充剩下的空间,使生成的二进制代码恰好为512字节
dw 0xaa55 ; 结束标志
用nasm编译生成一个512字节的obj文件(mbr)
然后用mbr工具什么什么的或者 磁盘编辑工具什么的把这512字节拷贝到0柱面、0磁头、1扇区(一个扇区就是512字节,不要在你的电脑上这么做,你可以把这512字节写到U盘上然后从U盘启动电脑就能看到效果,在虚拟机里面也行,具体怎么弄你可以参考于渊的著作《自己动手写操作系统》)
然后启动电脑就行了
对于问题1,和问题5
你想深入研究建议你去找一本介绍早期linux内核源代码的书籍来看一下
汇编程序在没有操作系统的情况下运行 相当于你在写操作系统,几乎没有功能的操作系统,你只能调用Bios中断!
在没有操作系统的情况运行 程序->你自己想象开发操作系统的过程吧!怎么运行我已经告诉你了!不会的话你找我要工具
我可以给你 nasm编译器,磁盘烧写工具!如果你需要我可以直接把二进制文件给你! 参考技术A 百度有介绍 参考技术B C语言是基础啊什么FPA
关于汇编语言问题,入栈出栈啥用
一个程序开始的时候,下面指令什么意思
PUSH DS
SUB AX, AX
PUSH AX
MOV AX, DAT
MOV DS, AX
SUB AX, AX ;AX—AX 结果存放在AX中,就是把0放在AX中
PUSH AX ;把AX压入栈中
MOV AX, DAT ;把DAT段地址放到AX中
MOV DS, AX ;把AX值放到DS中
POP入栈是把数据压入栈段中;PUSH出栈是把数据从栈段中拿出来;入栈与出栈是遵循先进后出的原则!入栈出栈其实是个临时存储数据作用!SS指向栈段的段地址,SP指向栈段的顶端。
希望我的回答对您有帮助,呵呵! 参考技术A 保护数据用。就是将DS AX 里的数据先暂存在堆栈里,这就是入栈(指令为PUSH)。然后,可以对它们进行操作而不会影响原来的数据。到需要原来的数据时,再出栈(POP) 。 参考技术B 用于缓存数据,保护寄存器或者进行寄存器与寄存器间数据传输。而且有些寄存器的值只能通过堆栈操作完成。比如程序寄存器的值CS只能通过堆栈操作完成读取:
push cs
pop bx; 或者 pop ds之类。
也用于子函数(子例程,通过Call指令调用)的参数传递。
CALL _SUB
_SUB: PUSH AX ; 保存AX
PUSH BX ; 保存BX
mov AX, 128; 因为下面会改写这两个寄存器
mov BX, 125;
.... ; 进行相关功能操作
POP BX ; 完成后恢复BX值
POP AX ; 完成后恢复AX值
RET 参考技术C 汇编语言中堆栈的操作有专门的语句指令。
入栈指令是:PUSH
出栈指令是:POP
比如:
MOV A,30H ;将一个压缩BCD码送累加器A
PUSH ACC ;压栈保护
ANL A,#0FH ;保留低四位
MOV 30H,A ;回送给30H
POP ACC ;出栈
SWAP A ;高低四位互换
ANL A,#0FH ;保留低四位
MOV B,#10 ;B送10
MUL AB ;乘10
ADD A,30H ;与个位相加
MOV 30H,A ;回送给30H
以上程序段将一个压缩BCD码转换为十六进制。 参考技术D 以上的回答,全都是错误的。
楼主的所问的这些指令:
PUSH DS
SUB AX, AX
PUSH AX
具有特定的含义,是不能简单的解释为:保护数据。
这几句,是和 DOS 操作系统配合使用的。
这几句,是为了正确结束应用程序,而编写的。
以上是关于关于汇编的几个问题的主要内容,如果未能解决你的问题,请参考以下文章