Pour certains contexte, je suis assez nouveau à l'assembleur, et mon assembleur de choix est NASM. Pour mon premier projet, j'utilise cygwin sur Windows 8.1, et j'ai essayé de convertir les informations de la seconde réponse sur cette question stackoverflow de 32 bits à 64 bits: How to write hello world in assembler under Windows?Je semble être incapable de résoudre cette erreur LD à partir d'un tutoriel WinAPI NASM
J'utilise gnu ld à la place de link.exe parce que le kernel32.Lib sur mon système semble être foiré, et je préfère de toute façon gnu ld. Donc, voici mon assembleur:
global _main
extern [email protected]
extern [email protected]
extern [email protected]
section .text
_main
push rbp
mov rbp, rsp
sub rsp, 4
; hStdOut = GetStdHandle(STD_OUTPUT_HANDLE)
push -11
call [email protected]
mov rbx, rax
; WriteFile(hStdOut, message, length(message), &bytes, 0)
push 0
lea rax, [rbp-4]
push rax
push (message_end - message)
push message
push rbx
call [email protected]
mov rsp, rbp
pop rbp
; ExitProcess(0)
push 0
call [email protected]
;
hlt
message db 'Hello, World!', 10
message_end
Quand je lance nasm -fwin64 ./test.asm
il assemble sans erreur, seuls les avertissements de me laisser les noms sur les colons de l'étiquette.
La commande que je utilise pour créer un lien vers le WinAPI est
ld test.obj -lkernel32 --enable-stdcall-fixup /cygdrive/c/Windows/system32/kernel32.dll -o test.exe
Cela me laisse
test.obj:./test.asm:(.text+0x1c): relocation truncated to fit: R_X86_64_32 against `.text'
Donc, j'utilisé Google à mon avantage et trouvé cette question stackoverflow: What does this GCC error "... relocation truncated to fit..." mean? J'ai lu le matériel dans la première réponse, et parcouru google un peu plus, puis essayé la solution offerte dans la deuxième réponse. Voici mon script éditeur de liens
SECTIONS
{
. = 0x000000000000001b;
.text :
{
*(*)
}
}
J'essaie de lier avec cette commande:
ld test.obj -T test.ld -lkernel32 --enable-stdcall-fixup /cygdrive/c/Windows/system32/kernel32.dll -o test.exe
Et je reçois cette erreur: ld: cannot find -lkernel32
Je reçois cette erreur, peu importe où je place le -T test.ld
option.
Je suis coincé et mon google-foo ne semble pas suffisant pour trouver de l'aide de cette façon. Je ne comprends pas pourquoi LD ne peut pas trouver kernel32 quand je spécifie un script d'éditeur de liens, et je ne sais pas non plus comment résoudre la troncature.
Si elle aide, le objdump avec les données de réinstallation pour test.obj
est:
$ objdump -Sr test.obj
test.obj: file format pe-x86-64
Disassembly of section .text:
0000000000000000 <_main>:
0: 55 push %rbp
1: 48 89 e5 mov %rsp,%rbp
4: 48 83 ec 04 sub $0x4,%rsp
8: 6a f5 pushq $0xfffffffffffffff5
a: e8 00 00 00 00 callq f <_main+0xf>
b: R_X86_64_PC32 [email protected]
f: 48 89 c3 mov %rax,%rbx
12: 6a 00 pushq $0x0
14: 48 8d 45 fc lea -0x4(%rbp),%rax
18: 50 push %rax
19: 6a 0e pushq $0xe
1b: 68 32 00 00 00 pushq $0x32
1c: R_X86_64_32 .text
20: 53 push %rbx
21: e8 00 00 00 00 callq 26 <_main+0x26>
22: R_X86_64_PC32 [email protected]
26: 48 89 ec mov %rbp,%rsp
29: 5d pop %rbp
2a: 6a 00 pushq $0x0
2c: e8 00 00 00 00 callq 31 <_main+0x31>
2d: R_X86_64_PC32 [email protected]
31: f4 hlt
0000000000000032 <message>:
32: 48 rex.W
33: 65 6c gs insb (%dx),%es:(%rdi)
35: 6c insb (%dx),%es:(%rdi)
36: 6f outsl %ds:(%rsi),(%dx)
37: 2c 20 sub $0x20,%al
39: 57 push %rdi
3a: 6f outsl %ds:(%rsi),(%dx)
3b: 72 6c jb a9 <message_end+0x69>
3d: 64 21 0a and %ecx,%fs:(%rdx)
Merci.
__SOLUTION EDIT__ pour les singes futurs Google:
En utilisant les informations contenues dans la réponse de @Jester, je réécrit le programme et il fonctionne maintenant comme prévu. Voici la source de travail:
global main
extern [email protected]
extern [email protected]
extern [email protected]
section .text
main
push rbp
mov rbp, rsp
sub rsp, 8
; hStdOut = GetStdHandle(STD_OUTPUT_HANDLE)
; ABI, pass in registers
mov rcx, -11
call [email protected]
mov rbx, rax
; WriteFile(hStdOut, message, length(message), &bytes, 0)
mov rcx, rbx
lea rax, [rel message]
mov rdx, rax
mov r8, (message_end - message)
lea rax, [rbp-8]
mov r9, rax
push 0
call [email protected]
mov rsp, rbp
pop rbp
; ExitProcess(0)
mov rcx, 0
call [email protected]
;
hlt
message db 'Hello, World!', 10
message_end
D'accord, merci! Le binaire est maintenant lié, mais génère une erreur de segmentation sur l'appel WriteFile(). Est-ce dû à la convention d'appel sur x64 (est-ce ARM ABI?). Dans ce cas, devrais-je déplacer les arguments dans les registres r comme décrit sur cette page ?: http://eli.thegreenplace.net/2011/09/06/stack-frame-layout-on-x86-64/ –
I vous avez lié la documentation officielle msdn ... et non, cela n'a rien à voir avec ARM. – Jester
Okay. Je l'ai eu maintenant, et j'ai mis à jour l'op avec la source de travail. Merci beaucoup! –