关于汇编的几个问题

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了关于汇编的几个问题相关的知识,希望对你有一定的参考价值。

有以下几个问题,希望高手能一一解答
1、系统是用汇编编写的么
2、汇编可不可以写可视化的程序,或者3D的
3、汇编编译出来的obj文件必须经过连接才可以执行么
4、obj可以连接成任意可执行文件,实现跨平台么
5、汇编的程序可不可以在没有操作系统的情况下运行,如果可以,怎么运行
就这些了,希望高手解答,能多少是多少。。

1:操作系统很庞大,操作系统的引导bootsect这个必须要由汇编来写,不过由于操作系统过于庞大,所以内核就由C(linux系统没有采用一条C++语句,即使是现在的linux内核也没有一条C++语法)来写了,具体的你可以看下Linux源代码,用到汇编的部分只有引导的部分,而那部分只能有汇编来写,这部分包括mbr,因为512B 的mbr每一个字节都有特定作用只能由低级语言来写。
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

PUSH DS ;把DS压入栈中
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 操作系统配合使用的。
这几句,是为了正确结束应用程序,而编写的。

以上是关于关于汇编的几个问题的主要内容,如果未能解决你的问题,请参考以下文章

关于warning no stack segment的问题 - 16位汇编语言代码问题

关于 GNU ARM 汇编程序的意外警告

关于汇编中push ebp和pop ebp指令的解释

关于汇编语言

关于 AT&T 汇编语法 (%esp,1)

关于汇编用法--1