Assembly 64位程序集修复错误

Assembly 64位程序集修复错误,assembly,64-bit,fixup,Assembly,64 Bit,Fixup,我正在尝试运行教授给我们的64位汇编的测试程序,但它不是正确的工作程序 错误是: 错误LNK2017:“ADDR32”重新定位到“naturals”无效,没有/LargeAddressware:否 致命错误LNK1165:由于修复错误,链接失败 代码是: ; no need for .386, .586, .MODEL directives in 64-bit programs .DATA sentence BYTE "Now is the winter of our discontent"

我正在尝试运行教授给我们的64位汇编的测试程序,但它不是正确的工作程序

错误是: 错误LNK2017:“ADDR32”重新定位到“naturals”无效,没有/LargeAddressware:否 致命错误LNK1165:由于修复错误,链接失败

代码是:

; no need for .386, .586, .MODEL directives in 64-bit programs

.DATA

sentence BYTE "Now is the winter of our discontent", 0h
firstWord BYTE 20 DUP (?)
space BYTE ' '

naturals QWORD 10 DUP (?)
sum QWORD ?

.CODE

main proc

    ; test out our getFirstWord procedure

    ; the second argument
    mov rax, offset firstWord
    push rax

    ; the first argument
    mov rax, offset sentence
    push rax

    call getFirstWord

    ; initialize our 'naturals' array
    mov rcx, 1
    mov rdi, 0

nextNumber:

    mov naturals[rdi*8], rcx



    inc rcx

    cmp rcx, 10
    jg initializationComplete

    inc rdi

    jmp nextNumber

initializationComplete:

    ; test out our sumArray procedure

    ; second argument (number of elements in array)
    mov rax, 10
    push rax

    ; first argument (array address, alternative to offset)

    lea rax, naturals
    push rax

    call sumArray

    ; store the result in memory
    mov sum, rax

    ; exit

    mov rax, 0
    ret

main endp

getFirstWord proc

    ;pop rax ; address of sentence
    ;pop rbx ; address of firstWord

    mov rax, [esp+8]
    mov rbx, [esp+16]
    mov rcx, 0
    mov cl, [space]

nextCharacter:
    cmp [rax], byte ptr 0   ; check for a null-terminator in the sentence
    je allDone

    cmp cl, [rax] ; check for a space in the sentence
    je nullTerminate

    mov dl, [rax] ; copy the current character
    mov [rbx], dl

    inc rax
    inc rbx

    jmp nextCharacter

nullTerminate:

    inc rbx
    mov byte ptr [rbx], 0

allDone:

    ret 16

getFirstWord endp

sumArray proc

    ; get the address of the array
    mov rax, [rsp+8]

    ; get the number of elements in the array
    mov rcx, [rsp+16]

    xor rbx, rbx  ; initialize sum to zero
    xor rsi, rsi  ; initialize counter to zero

nextArrayElement:
    add rbx, [rax]
    add rax, 8

    inc rsi

    cmp rsi, rcx
    je finishedSum

    jmp nextArrayElement

finishedSum:

    mov rax, rbx

    ret 16

sumArray endp

END

我尝试将LargeAddressWare设置为否,程序将编译和生成,但没有输出。是否假设没有任何输出,只需要运行它?还是说那个设置把事情搞砸了?我也尝试过改变naturals的移动方式,但唯一起作用的是改变地址设置。

你应该使用
rsp
而不是
esp
。另外,请注意,64位模式下的标准调用约定使用寄存器传递前几个参数(但您自己的代码不必这样做。)至于输出,我没有看到任何生成输出的代码,所以这是预期的。附言:学会使用英语debugger@Jester实际上,您自己的代码必须这样做才能使操作系统堆栈展开工作。除了其他注释外,我冒昧地猜测导致链接器错误的行是
mov naturals[rdi*8],rcx
naturals
是表示标签地址的64位值。您将其用作位移,但在64位模式下,内存操作数上的位移为32位(它将符号扩展为64位),您可以执行
learsi,offset naturals
,然后使用类似于
mov[rsi+rdi*8],rcx
的操作来无输出,我看不到您在向控制台输出任何数据。MSVC工具链的默认代码模型是什么?在Linux中,所有工具的默认代码模型都是“小”:。因此,您可以而且应该使用类似于
moveax、offset firstWord
的东西。此外,您可以将示例缩小很多,因为您会在一个小示例中遇到相同的链接器错误,该示例只有一行mov naturals[rdi*8],rcx。