要使正常(接近直接相对)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绝对不能用于我想要实际使用的任何代码。
答案 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
链接。从理论上讲,这可能可以解决在目标文件中表示重定位的问题,并获得链接器以计算相对分支位移。