64位NASM CALL FAR 调用问题

太虚野老 2017-09-14 03:16:17
AMD处理器,64位环境,在NASM中,使用如下代码:
strlen_pointer:
dd test
dw 0x33
call far dword [strlen_pointer]
test:

编译通过,反汇编时生成的机器码也正确,但机器码的组织有问题,导致运行时出错:

我想实现的功能如下:

问题出在哪儿?
...全文
1913 15 打赏 收藏 转发到动态 举报
写回复
用AI写文章
15 条回复
切换为时间正序
请发表友善的回复…
发表回复
煎蛋不怕煎 2019-06-28
  • 打赏
  • 举报
回复
不应该是qword吗
太虚野老 2017-09-21
  • 打赏
  • 举报
回复
这段测试代码在VS中可以运行,在IDA 的Windbg debugger中也可以运行,但是在IDA的Local Bochs debugger中运行时报错: 观察堆栈,可以看到RIP和CS并没有入栈: 应该入栈的RIP为0000000000401006:
太虚野老 2017-09-21
  • 打赏
  • 举报
回复
完整的测试代码: TITLE (test.asm) EXTERN MessageBoxA: proc .data text db 'Hello x64!', 0 caption db 'My First x64 Application', 0 strlen_pointer: dd _strlen dw code16_sel code16_sel equ 33H public main .code main : call fword ptr [strlen_pointer] mov rax,10000h ; RAX = 10000h add rax,40000h ; RAX = 50000h sub rax,20000h ; RAX = 30000h sub rsp,28h xor r9d,r9d lea r8, caption lea rdx, text xor rcx,rcx call MessageBoxA add rsp,28h ret _strlen: mov rax,10000h ;db 48h retf END ;END main,donot use main
  • 打赏
  • 举报
回复
我估计这是因为bochs是一个x86/x64仿真环境,并非真机调试,某些指令可能解释得有问题,只要原生环境能运行就可以。
  • 打赏
  • 举报
回复
public main, winmain .code main: winmain:
太虚野老 2017-09-20
  • 打赏
  • 举报
回复
不行: 1>LINK : error LNK2001: 无法解析的外部符号 main
  • 打赏
  • 举报
回复
把 main PROC main ENDP 两行删掉。
太虚野老 2017-09-20
  • 打赏
  • 举报
回复
不行,还是这个错误。
  • 打赏
  • 举报
回复
dd offset _strlen
太虚野老 2017-09-20
  • 打赏
  • 举报
回复
下面是我写的一段MASM的代码,但是编译时报错: TITLE (test.asm) TITLE 在IDA PRO中调试时,需使用Local Bochs debugger EXTERN MessageBoxA: proc .data text db 'Hello x64!', 0 caption db 'My First x64 Application', 0 strlen_pointer: dd _strlen dw code16_sel code16_sel equ 33H .code main PROC call fword ptr [strlen_pointer] mov rax,10000h ; RAX = 10000h add rax,40000h ; RAX = 50000h sub rax,20000h ; RAX = 30000h sub rsp,28h xor r9d,r9d lea r8, caption lea rdx, text xor rcx,rcx call MessageBoxA add rsp,28h ret _strlen: mov rax,10000h db 48h retf ;call ExitProcess main ENDP END ;END main,donot use main 错误信息: 1>test.asm(10): error A2006: undefined symbol : _strlen
  • 打赏
  • 举报
回复
我试了一下,nasm只要直接call far [xxx]就可以,masm需要call fword ptr [xxx]。 需要注意的是不论nasm、masm在64位模式下的far return指令都没有生成rex.w前缀,必须手工补上才能正确返回。 另外,虽然intel手册上说了call far m16:32在64位模式下可用,但实测会产生异常,即便连接时用/largeaddressaware:no限制加载在4GB以上地址也不行。必须要用call far m16:64才行,而该指令在amd64处理器上并不支持。amd64上不支持80位far地址,只认48位far地址。 global _start section .data use64 farptr: dq test1 ; for intel64 only dw 33h section .code use64 _start: call far [farptr] ret test1: db 48h retf
太虚野老 2017-09-17
  • 打赏
  • 举报
回复
引用 2 楼 DelphiGuy 的回复:
呃,MASM/TASM要用call fword ptr [strlen_pointer]
请给出在64位MASM中实现该功能的完整代码清单。
太虚野老 2017-09-16
  • 打赏
  • 举报
回复
fword 编译出错: 1>x64Nasm.asm(15): error : comma, colon, decorator or end of line expected after operand
  • 打赏
  • 举报
回复
呃,MASM/TASM要用call fword ptr [strlen_pointer]
  • 打赏
  • 举报
回复
应该是call fword [strlen_pointer]

21,458

社区成员

发帖
与我相关
我的任务
社区描述
汇编语言(Assembly Language)是任何一种用于电子计算机、微处理器、微控制器或其他可编程器件的低级语言,亦称为符号语言。
社区管理员
  • 汇编语言
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧