64位的汇编怎么搞

Posted

tags:

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

我用masm汇编程序之后不能直接运行在Windows 7 x64,必须用VM或者用dosbox来运行。我想问一下有没有什么汇编合适x64的系统的,难道要别人装了虚拟机才能运行我的程序,如果没有,那现在的x64环境的软件是怎么来的?如果有满意答案再加50分
别跟我说用高级语言(Java,C++),我主要是想学汇编,Java之类的不太好

用32位汇编器或者64位汇编器。

masm我没用过,不知道有没有x86-32和x86-64版

我用过的nasm、yasm都能输出x86-32和x86-64的obj文件,配合其他linker即可生成可执行文件
fasm配合它给你准备好的那些宏的头文件可以不需要linker直接生成exe,但是fasm用了几次感觉不怎么用的来。
此外还有goasm啥的听过没用过。

gcc编译器套装里面带有一个gas,简单用过一两下但是不怎么好用,感觉它主要是作为编译器后端用的不是给你直接用的。

不过反正windows下又不给你直接通过中断方式使用系统调用(也不是完全不行,没这个必要,不同版本windows系统的系统调用号和参数啥的又不一样),最终还是要用那些dll里面的api,所以linker还是必要的吧。
nasm和yasm里面不带linker就是了,你可以用pelles c compiler套装里面的linker,或者go asm套装里面的linker(没用过),更直接一点有装vc啥的直接用vc里的linker也成

x64环境的软件?高级语言啊……追问

我想问一下什么汇编能够在x64的环境下编译成exe和运行,不要说一大堆给个直接的,我会采纳你

追答

你要先搞清楚编译和链接的关系啊。因为我平时用的汇编器都是只编译不链接的,说简单点就是只出obj不出exe的。


fasm根据它例子写出来长这样

format PE64 GUI
entry main

section '.code' code readable executable
main:
    sub rsp, 40
    mov r9d, 0
    lea r8, [mb_title]
    lea rdx, [mb_content]
    xor rcx, rcx
    call [MessageBoxA]
    add rsp, 40
    ret

section '.data' code readable writeable
    mb_title db 'Message', 0
    mb_content db 'Hello world!', 0

section '.idata' import data readable writeable
    dd 0, 0, 0, RVA u32_name, RVA u32_table
    dd 0, 0, 0, 0, 0
    
    u32_table:
        MessageBoxA dq RVA mbox_name
        dq 0
    
    u32_name:
        db 'user32.dll', 0
    
    mbox_name dw 0
        db 'MessageBoxA', 0

连导入表什么的也要自己构建……没搞过这样的,不过反正是能出exe能运行。出来的exe才2k

参考技术A 64汇编不同于masm,所谓的学习汇编还是还是要老环境。 参考技术B 你的16位程序跑不了了,WIN X64下已经去掉了WOW32了,也就是NTVDM没了 参考技术C 用visual studio带的ml64

汇编语言寄存器存储器问题

汇编语言里寄存器是指通用寄存器AX BX CX DX SP BP DI SI还是段寄存器?加方括号是不是就是存储器?REG/MEM/SREG 怎么判断存储器的位数?8位16位32位? 立即数有宽度位数的吗?0012H和12H一样宽吗?

通用寄存器8个:AX BX CX DX SP BP DI SI
加方括号就是存储器,存储器之间不能传递数据
REG寄存器
MEM储存器
SREG状态寄存器
立即数有宽度,但要看怎么用:mov ax,12h就是16位的,mov al,12h就是8位的,但不能mov al,0012h
参考技术A 寄存器有通用寄存器,段寄存器,标志寄存器
其中通用寄存器:
EAX:累加寄存器,是32位的 可以取低16位单独使用,叫AX,其中AX,又可以分成一半一半 8高位的叫AH 底8位的叫AL
其他(E)BX,(E)CX,(E)DX用法一样(所以你看到BL就知道它是8位的寄存器,看到DX就知道它是16位的寄存器)

而段寄存器有 SS CS FS GS

汇编里讲到段寄存器时 一般根据功能判断是什么寄存器

至于加上括号 不是说不是寄存器,而是寄存器寻址的一种表示方法:
例如:MOV AX,[DS][DI]
是把DS+DI值对应的地址的内容给AX

立即数是有宽度的,例如
MOV AX,97H 就会报错 因为AX是16位寄存器 而97H则是8位立即数(这时可以用CDW进行类型转换,把97H变成0097H)
参考技术B 请说明JMP DI和JMP [DI]指令的区别.
DI就是指放进它里面的东西,如一个内存单元的偏移地址0001H;[DI]表示存储单元里的内容,如偏移地址为0001H内存单元里面放着数据12H,那么[DI]就是指12H.
1.用寄存器BX和SI的基址变址寻址方式,把存储器中的一个字节与AL寄存器的内容相加,并把结果送回存储器中.
ADD AL,[BX][SI]
2.用寄存器BX和位移量0B2H的寄存器相对寻址方式把存储器的一个字和(CX)相加,并把结果送回存储器中.
ADD [BX+B2H],CX
3.用位移量为0524H的直接寻址方式把存储器中的一个字与数2A59H相加,并把结果送回该存储单元中.
题目打错了吧?0524H应该是偏移地址吧。这样的话,代码如下:
MOV AX,2A59H
ADD [0524H],AX
请参考
参考技术C 寄存器是一个总称,它分为通用寄存器和段寄存器等等,当然还有其它的寄存器如CR0等,只是在win32环境完全没必要了解,因为没有特权对它们进行操作,只有更高的特权级如操作系统内核才能对它们进行操作。
如果你是新手可能你还不知道,汇编语言是有很多个种类的有masm,nasm,tasm等等,每一种汇编的语法都有分别,我学的是nasm加方括号如mov [bx], 0,是间接寻址,即取bx的内容作为内存地址寻址。
参考技术D 寄存器是CPU内部的通用寄存器和段寄存器的总称,如果在寻址的时候用方括号就代表着间接寻址,也就是在内存中找数据。。你可以去饭客网络详细的学习下汇编知识

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

如何在64位的linux系统上使用汇编和C语言混合编程

如何在64位的Linux系统上使用汇编和C语言混

x86_64 汇编 Linux 系统调用混淆

x64汇编第一课

win10 64位 汇编环境

视频更新:代码分析8之单步调试ARM64启动汇编与重定位