如何在MASM中为近直接相对调用/ jmp写一个绝对目标

时间:2018-04-27 08:39:22

标签: assembly visual-c++ x86 call masm

要使正常(接近直接相对)call为绝对地址,在NASM或AT& T语法中编写call 0x1234567,汇编程序+链接器负责计算{{1}从链接器放置rel32指令的任何地方到达该目标。

e.g。在Linux上将其组装成一个带有call的静态64位ELF可执行文件,然后用yasm -felf64 foo.asm && ld foo.o -o foo反汇编为您提供:

objdump -drwC -Mintel foo

链接器根据目标文件中的foo: file format elf64-x86-64 Disassembly of section .text: 0000000000400080 <_start>: 400080: e8 e2 44 e3 00 call 1234567 <_end+0xc344df> 重定位计算出正确的rel32从0x1234567到达0x400080+5

R_X86_64_PC32

如何让MASM和/或MSVC inline-asm这样做?

MSVC不接受 0: e8 00 00 00 00 call 5 <_start+0x5> 1: R_X86_64_PC32 *ABS*+0x1234563 。错误是_asm { call 1234567h; }The only SO answer I've found建议使用间接jmp的解决方法,使用内存中的地址或寄存器,但由于难以使用的工具而制作低效的机器代码并不是一个很好的解决方案。

我根本没有MASM,所以我只能尝试MSVC inline-asm(这不是一回事)on the Godbolt compiler explorer

您可以设置标签的地址并将其用作C2415: improper operand type的目标吗?与GAS的call symbol一样,它允许您为符号提供地址,而不必在任何地方实际编写.set symbol, 0x1234567

您可以使用symbol: / db 0E8h直接发出编码吗?可能不是,in NASM that only works with label - $,而不是dd 1234567h - ($ + 4)

我最感兴趣的答案所以我可以将它包含在关于jmp /调用绝对地址的规范答案中:Call an absolute pointer in x86 machine code绝对不能用于我想要实际使用的任何代码。

1 个答案:

答案 0 :(得分:1)

MASM不支持此功能,因为COFF目标文件格式不支持必要的重定位。 (或者正确不支持它?根据NASM错误消息。)

TestBed.overrideProvider(ActivatedRoute, {useValue: mockActivatedRoute}); TestBed.overrideProvider(SecurityService, {useValue: mockSecurityService}); fixture = TestBed.createComponent(LoginComponent); fixture.detectChanges() 中使用call 0x76cd75c0语法会产生错误:

nasm -f win32

我不知道以实模式平面二进制文件为目标的MASM是否可以做到(没有目标文件必须描述链接器的重定位),但是不幸的是,MASM的设计根本没有语法。


另请参见Error when calling function in user32.dll directly。我确实在Linux桌面上尝试error: Win32 COFF does not correctly support relative references to absolute addresses 2.13.02并遇到相同的错误。


未经测试的可能解决方法可能是创建带有该绝对地址的符号定义的nasm -fwin32,例如

.obj

在NASM中,或者您在MASM中进行。

然后在MASM或MSVC内联汇编中,您可以使用org 0deadbeefH global my_target my_target: 并与该jmp my_target链接。从理论上讲,这可能可以解决在目标文件中表示重定位的问题,并获得链接器以计算相对分支位移。