我正在尝试在linux ubuntu 32位中编译汇编代码。
但是当我用nasm -felf32 assembly.asm && gcc assembly.o && ./a.out
编译它时,我面对Segmentation fault (core dumped)
。我明白问题在于printf。
我在互联网上搜索了很多,有几个这样的问题。但没有一个答案对我有用。
global main
extern printf
section .text
main:
push ebx ; we have to save this since we use it
mov ecx, 90 ; ecx will countdown to 0
xor eax, eax ; rax will hold the current number
xor ebx, ebx ; rbx will hold the next number
inc ebx ; rbx is originally 1
print:
; We need to call printf, but we are using rax, rbx, and rcx. printf
; may destroy rax and rcx so we will save these before the call and
; restore them afterwards.
push eax ; caller-save register
push ecx ; caller-save register
mov edi, format ; set 1st parameter (format)
mov esi, eax ; set 2nd parameter (current_number)
xor eax, eax ; because printf is varargs
; Stack is already aligned because we pushed three 8 byte registers
call printf ; printf(format, current_number)
pop ecx ; restore caller-save register
pop eax ; restore caller-save register
mov edx, eax ; save the current number
mov eax, ebx ; next number is now current
add ebx, edx ; get the new next number
dec ecx ; count down
jnz print ; if not done counting, do some more
pop ebx ; restore rbx before returning
ret
format:
db "%20ld", 10, 0
***源代码是从Nasm tutorial site复制的。它用于打印斐波那契数字。
答案 0 :(得分:1)
这对于所有这些大惊小怪的问题来说太容易了。您已经找到了64位教程,将其转换为32位并不像将rax
更改为eax
那么简单。以下是您在32位代码中调用printf
的方法。
print:
; We need to call printf, but we are using rax, rbx, and rcx. printf
; may destroy rax and rcx so we will save these before the call and
; restore them afterwards.
; comment does not match code!
push eax ; caller-save register
push ecx ; caller-save register
push eax ; (current number)
push format ; set 1st parameter (format)
call printf ; printf(format, current_number)
add esp, 4 * 2 ; "remove" 2 parameters - 4 bytes each
pop ecx ; restore caller-save register
pop eax ; restore caller-save register
; etc...
print:
; We need to call printf, but we are using rax, rbx, and rcx. printf
; may destroy rax and rcx so we will save these before the call and
; restore them afterwards.
; comment does not match code!
push eax ; caller-save register
push ecx ; caller-save register
push eax ; (current number)
push format ; set 1st parameter (format)
call printf ; printf(format, current_number)
add esp, 4 * 2 ; "remove" 2 parameters - 4 bytes each
pop ecx ; restore caller-save register
pop eax ; restore caller-save register
; etc...
那是未经测试的。只有32位,我认为你不会得到完整的90个数字。您可能需要更改字符串。通过使用两个寄存器,您可以使用32位代码获得64位结果,但是您没有代码...