Assembly 64位程序集修复错误
我正在尝试运行教授给我们的64位汇编的测试程序,但它不是正确的工作程序 错误是: 错误LNK2017:“ADDR32”重新定位到“naturals”无效,没有/LargeAddressware:否 致命错误LNK1165:由于修复错误,链接失败 代码是: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"
; 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。