-
Notifications
You must be signed in to change notification settings - Fork 277
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Cygwin: ST Support Windows 64bits #20
Comments
Run utest for Cygwin64:
应该返回成功才对:
|
ASM for Cygwin64Cygwin64的数据和ASM汇编实现摘要。 jmpbuf定义在文件
也就是说,jmpbuf的定义如下:
因此,获取SP的宏定义,直接取对应的位置就可以:
Calling Convention函数调用的参数说明,参考x64 calling convention,ST的函数比较简单:
对于
Registers寄存器规划参考Understanding Windows x64 Assembly。 被调用函数可以用的寄存器,也就是汇编函数中可以自己使用的寄存器:
调用者用的寄存器,汇编的函数如果要用这些寄存器就要push和pop:
因此,规划ST的寄存器使用如下:
特别说明如下:
ASM: Intel or AT&TASM实际上有两种风格:Intel和AT&T,比如FFmpeg以及NASM的汇编都是Intel风格,而GNU的是AT&T风格,所以在GDB中看到的都是AT&T风格,但可以设置为Intel风格: (gdb) set disassembly-flavor intel 这样就可以看到汇编代码变成Intel风格了: gdb ./win-nasm-hello
Set disassembly flavor to intel ok.
(gdb) disassemble main
Dump of assembler code for function main:
0x0000000100401080 <+0>: push rbp
0x0000000100401081 <+1>: mov rbp,rsp
0x0000000100401084 <+4>: sub rsp,0x20
0x0000000100401088 <+8>: lea rcx,[rip+0xf81] # 0x100402010 <msg>
0x000000010040108f <+15>: call 0x1004010b0 <printf>
0x0000000100401094 <+20>: xor rax,rax
0x0000000100401097 <+23>: call 0x100401698 <ExitProcess>
0x000000010040109c <+28>: nop DWORD PTR [rax+0x0] Call and Ret当使用汇编指令 void foo() {
}
int main(int argc, char** argv) {
foo();
return 0;
} 编译成汇编指令是: Dump of assembler code for function main(int, char**):
0x000000010040109b <+20>: call 0x100401080 <_Z3foov>
0x00000001004010a0 <+25>: mov eax,0x0
Dump of assembler code for function _Z3foov:
0x0000000100401080 <+0>: push rbp
0x0000000100401081 <+1>: mov rbp,rsp
0x0000000100401084 <+4>: nop
0x0000000100401085 <+5>: pop rbp
0x0000000100401086 <+6>: ret 我们查看寄存器和Stack的内容,调用前RSP的内存是全零: (gdb) i r rsp rbp rip
rsp 0x7ffffcbe0 0x7ffffcbe0
rbp 0x7ffffcc00 0x7ffffcc00
rip 0x10040109b 0x10040109b <main(int, char**)+20>
(gdb) x/8xb $rsp
0x7ffffcbe0: 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 使用 (gdb) i r rsp rbp rip
rsp 0x7ffffcbd8 0x7ffffcbd8
rbp 0x7ffffcc00 0x7ffffcc00
rip 0x100401080 0x100401080 <foo()>
(gdb) x/16xb $rsp
0x7ffffcbd8: 0xa0 0x10 0x40 0x00 0x01 0x00 0x00 0x00
0x7ffffcbe0: 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00
因此,如果我们要写汇编实现foo,在foo中获取caller的RSP,就可以用当前RSP加8即可: lea r8, [rsp+0x8]
# Equal to:
mov r8, rsp
add r8, 8
一般函数的实现,都是将RBP保存到stack、将RBP指向RSP、创建Home space: foo:
push rbp
move rbp, rsp
sub rsp, 0x20 而在函数返回前,做相反的操作,比如: foo:
add rsp, 0x20
pop rbp
ret
# Or
mov rsp, rbp
pop rbp
# Or
leave
ret
一般我们在实现ST的过程中,并不会实现标准的函数的堆栈这些调用,而是选择直接将寄存器保存后 Backtrace当我们使用gdb的bt命令查看堆栈时,本质上就是做了两个事情:
所以实际上我们可以使用下面的命令查看caller的信息: (gdb) disassemble main
Dump of assembler code for function main(int, char**):
0x0000000100401087 <+0>: push rbp
0x0000000100401088 <+1>: mov rbp,rsp
0x000000010040108b <+4>: sub rsp,0x20
0x000000010040108f <+8>: mov DWORD PTR [rbp+0x10],ecx
0x0000000100401092 <+11>: mov QWORD PTR [rbp+0x18],rdx
0x0000000100401096 <+15>: call 0x1004010c0 <__main>
0x000000010040109b <+20>: call 0x100401080 <_Z3foov>
0x00000001004010a0 <+25>: mov eax,0x0
0x00000001004010a5 <+30>: add rsp,0x20
0x00000001004010a9 <+34>: pop rbp
0x00000001004010aa <+35>: ret
End of assembler dump.
(gdb) disassemble foo
Dump of assembler code for function _Z3foov:
0x0000000100401080 <+0>: push rbp
0x0000000100401081 <+1>: mov rbp,rsp
=> 0x0000000100401084 <+4>: nop
0x0000000100401085 <+5>: pop rbp
0x0000000100401086 <+6>: ret
End of assembler dump.
(gdb) x/16xb $rbp
0x7ffffcbd0: 0x00 0xcc 0xff 0xff 0x07 0x00 0x00 0x00
0x7ffffcbd8: 0xa0 0x10 0x40 0x00 0x01 0x00 0x00 0x00 可以看到 (gdb) bt
#0 foo () at hello.cpp:6
#1 0x00000001004010a0 in main (argc=1, argv=0xa00001690) at hello.cpp:9
(gdb) f 1
#1 0x00000001004010a0 in main (argc=1, argv=0xa00001690) at hello.cpp:9
9 foo();
(gdb) i r rbp
rbp 0x7ffffcc00 0x7ffffcc00 如果我们在创建协程时,也把caller的Stack结构也创建了(内容可以是全零),这样就可以在gdb bt时看到整个调用栈了。 Cygwin ASM HelloWorld参考Understanding Windows x64 Assembly,编写汇编代码如下: bits 64
default rel
segment .data
msg db "Hello World, Cygwin ASM!", 0xd, 0xa, 0
segment .text
global main
extern printf
extern ExitProcess
main:
push rbp
mov rbp, rsp
sub rsp, 32
lea rcx, [msg]
call printf
xor rax, rax
call ExitProcess 编译执行: nasm -f win64 -o win-nasm-hello.o win-nasm-hello.asm &&
g++ -o win-nasm-hello win-nasm-hello.o &&
./win-nasm-hello 注意例子中用的是link,而在cygwin中这个是创建文件链接的命令。在Cygwin中链接,所以可直接用g++链接。 Debugging By GDB使用汇编调试,用TUI模式汇编代码: (gdb) layout next
(gdb) la n 查看所有寄存器,或者某些寄存器: (gdb) help i r
#info registers, info r
(gdb) i r rip rbp rsp
#rip 0x100401081 0x100401081 <main+1>
#rbp 0x7ffffcd30 0x7ffffcd30
#rsp 0x7ffffcc00 0x7ffffcc00 查看RSP堆栈寄存器指向的内存内容: (gdb) x/16xb $rsp
0x7ffffcbd8: 0xa0 0x10 0x40 0x00 0x01 0x00 0x00 0x00
0x7ffffcbe0: 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 这样可以方便看到寄存器的变化。 |
For https://github.com/wenjiegit to port SRS to Windows by msys2 or cygwin.
Usage
Download and install Cygwin setup-x86_64.exe
Select mirror, for exmaple, aliyun
https://mirrors.aliyun.com/cygwin/
devel
categoryCygwin64 Terminal
The text was updated successfully, but these errors were encountered: