首页 > 编程语言 >【汇编】汇编的helloWorld

【汇编】汇编的helloWorld

时间:2023-08-01 17:45:17浏览次数:38  
标签:汇编 exe 16 程序 mov helloWorld SA PSP

过程

汇编源代码 -> 编译 -> 链接 -> 执行exe。

编译:将源码翻译成机器代码,生成目标(obj)文件。有 x 个源码文件就会生成 x 个目标文件。
链接:将目标文件进行链接,生成exe文件。

在dos中,shell是一直运行的进程,当执行汇编exe时,shell会将exe加载进内存,shell中断暂停运行,并设置CPU的CS:IP指向入口。exe执行结束后中断返回至shell,shell继续运行。

exe

exe中包含两部分文件,程序(exe)和数据;相关的描述信息(map),比如程序有多大,占用的内存空间等。

在操作系统中,操作系统依照可执行文件中的描述信息,加载机器码和数据,并进行相关初始化(比如设置cs:ip指向第一条要执行的指令),然后CPU执行程序。

dos加载exe的过程

  1. 找到一段起始地址SA:0,起始地址的偏移地址为0的容量足够的空闲内存区。
  2. 在这个内存去的前256个字节,创建一个数据区(PSP),DOS利用PSP来和家在程序进行通信。
  3. 程序被加载在PSP后面,程序地址被设为SA+10H:0。
  4. 将该内存区的段地址存入ds,初始化其他寄存器,设置CS:IP指向程序的入口。

为什么是 SA+10H:0

程序加载后,ds存放着程序所在内存区的段地址,这个内存区的偏移地址为0,即地址为ds:0。

这个内存区的前256个字节是PSP,256之后是程序。

所以,PSP的段地址是SA,PSP偏移地址是0,所以物理地址是SA*16 + 0。
因为PSP占用256字节,所以程序物理地址是:

SA * 16 + 0 + 256 = SA * 16 + 16 * 16 + 0 = (SA+16)*16 + 0
简化乘法分配律,即得SA + 10H:0。

SA * 16 + 0 是起始地址,加上 PSP 的大小后就是程序的物理地址。

源码分析

assume cs:code, ds: data, ss: stack

data segment
         dw 1, 2, 3, 4
data ends

stack segment stack
          dw 0H,0H,0H,0H

stack ends

code segment
             
    start:   mov  ax, stack
             mov  ss, ax
             mov  sp, 16
             
             mov  ax, data
             mov  ds, ax
             mov  cx, 8

             mov  ax, 4c00h
             int  21h

code ends

end start

伪指令

汇编指令有对应的机器码指令,可以被编译为机器指令,CPU最终执行。
伪指令是编译器来执行的指令,编译器根据伪指令来进行相关的编译工作。

XXX segemnt / XXX ends

这是一对指令伪指令,作用是定义一个段,segment说明一个段开始,ends说明一个段结束。

段名 segment
  ...
段名 ends

这里的段名可以任意取名。

end

这里的end是end start中的end,不是段的ends,代表了对源程序的编译,写完程序要加上end,不然编译器不知道在何时结束。

start

start是一个标号,代表程序入口在此。程序加载到内存后,CS:IP会指向这个标号,从start指向的指令开始运行。

start换成main也行,start不一定在程序代码最前面,也有可能在中间,前面是可以有指令或者数据的,但这样很不规范,在代码段里放置变量。

assume

定义标记符,将segement...end的段和某一寄存器相关联。

assume cs:code
定义了一个代码段,使用了assume来关联了cs寄存器。

程序的返回

当程序运行结束之后就要返回,返回程序段如下。

mov ax, 4c00H
int 21H

调用 INT 21H 的 4CH 号中断,安全退出程序。

标签:汇编,exe,16,程序,mov,helloWorld,SA,PSP
From: https://www.cnblogs.com/hatsuzuki/p/17596706.html

相关文章

  • 【汇编】栈
    栈栈的基础概念先出后出的一种数据结构。栈的地址由ss:sp指向的内存地址位置为栈段地址,栈的大小由sp控制,sp是栈顶指针,任意时刻指向栈顶。sp指针当有数据入栈时,从高位地址移向低位地址。当栈为空的时候,栈内没有元素,也就不存在栈顶元素。ss:sp指向栈的最底部单元下面的单元,地......
  • 【汇编】王爽《汇编语言(第3版)》相关习题
    P25检测点2.2(1)偏移地址的取值范围在0H~FFFFH之间。仅通过变化偏移地址寻址,根据物理地址计算公式:段地址*10H+偏移地址。已知段地址固定0001H,即最小物理地址为00010H,最大地址为1000FH。(2)设偏移地址为x,即公式为:SA*10H+x=20000H。偏移地址的取值范围......
  • gdb 反汇编disas源码排列问题
    问题在开发过程中,可能需要查看cpp文件生成的汇编代码来确认一些问题。由于单纯的汇编代码看起来并不太容易捋清楚内部逻辑,所以最好能够把源代码的位置列出来。在gdb的早期版本中,这个功能是通过disas命令的/m修饰符(选项)来实现的。如果使用过这个选项就会发现,这个功能显示的结果......
  • 汇编-jmp无条件转移指令
             ......
  • x86-64 汇编传参
    关于64位汇编的参数传递当参数少于7个时,参数从左到右放入寄存器:rdi,rsi,rdx,rcx,r8,r9。当参数为7个以上时,前6个与前面一样,但后面的依次从“右向左”放入栈中,即和32位汇编一样。参数个数大于7个的时候H(a,b,c,d,e,f,g,h);a->%rdi,b->%rsi,c->%r......
  • Ruby实践—HelloWorld
    开发环境OS:WindowsXPRuby:Ruby1.9.1Rails:Rails2.3.5IDE:RubyMine2.0.1 1、创建Rails工程 2、修改/config/database.yml自动创建的工程中默认数据库连接的是sqlite,如果没有安装此数据库,需要修改该配置(本例中使用的是mysql)#MysqlVersion5.1.46development:adapter:mys......
  • docker配置文件输出helloworld
    1.在root下创建dockerfilesudo-itouchDockerfilevimDockerfile2.编写helloworld.gopakagemainimport"fmt"funcmain(){fmt.Println("Hello,World!")} 3.配置DockerfileFROMubuntu:22.04ASv1ENVMYNAME="WANGYIDI"WOR......
  • 汇编与C
     @汇编中的符号@1.指令:能够编译成议题哦32bit机器码,并且能被cpu识别和执行@2.伪指令:本身不是指令,编译器可以将其替换成若干条指令@3.位操作:不会生成指令,只是在编译阶段告诉编译器这么编译@ARM指令集@1.数据处理指令:进行数学运算、逻辑运算@2.跳转指......
  • 汇编语言中ifidn和ifdif的作用
    来源在isa-l项目里的汇编文件中看到了有ifidn之类的写法,代码如下。第一遇到,便查阅资料记录一下用法。%ifidn__OUTPUT_FORMAT__,elf32[bits32]%elsedefaultrel[bits64]ifidn或IFIDN(大小写都可以),是两条伪指令,用于对两个宏定义的参数进行比较,最初误以为用法类似条件......
  • CGO输出helloworld
    使用CGO输出helloworld本人windows版本goversiongo1.18.3windows/amd64dir目录:D:\cgo\mainModeLastWriteTimeLengthName---------------------------d-----2023/7/1921:59......