I am struggling with my program for unfortunatelly tomorrow. I was supposed to write program in assembly rotationg 24bpp square bmp image for x86 and x86-x64 platforms. Version for x86 for 32bit processor works fine, howewer i have problem with converting it to 64bit.
Compilation code:
nasm -f elf64 rot64.asm && cc -m64 -o project64 project.c rot64.o && ./project64 picture.bmp
void rotbmp24(void *r9, int width)
Below i put working code for 32bit processor and not working for 64bit:
32bit version:
; void rotbmp24(void *img, int width);
; Rotate a 24 bpp square .BMP image of any size 90 degrees clockwise.
global rotbmp24
;define addresses of parameters passed by caller
%define img [ebp+8] ;pointer to bmp image
%define width [ebp+12] ;address of width
; allocation of place in memory for local variables
%define row_bytes [ebp-4]
%define img_line [ebp-8]
%define img_collumn [ebp-12]
%define img_width [ebp-16]
rotbmp24:
; making stack frame
push ebp
mov ebp, esp
sub esp, 16
; prologue
push ebx
push esi
push edi
; calculate row size
mov eax, width ; row size in pixels
mov edx, eax ;preserve eax
imul edx, 3 ; row size* in bytes (3 bytes per pixel)
add edx, 3 ; 3 is the maximum value to fit on 2 least sign. bits
and edx, 0fffffffch ; zero out 2 least sign. bits, to round up to multiple of 4
mov row_bytes, edx ; row size in bytes (multiple of 4)
; img_width variable is now width of our bmp image
mov img_width, eax
; pixel line
mov esi, img
mov img_line, esi
; pixel collumn
sub eax, 1
mov edi, eax ;preserve eax
imul edi, 3 ; row size* in bytes (3 bytes per pixel)
mul dword row_bytes ; eax=eax* (row_bytes, set to 32b)
add edi, img
add edi, eax
mov img_collumn, edi ;last row
changebyte:
; change rows into collumns
mov eax, [esi] ;first element
mov edx, [edi] ;last row element
mov ebx, eax ;duplicate them
mov ecx, edx
and eax, 00ffffffh ;check if given bits are...
and edx, 00ffffffh
and ebx, 0ff000000h
and ecx, 0ff000000h
or eax, ecx ;put bits together
or edx, ebx
mov [edi], eax ;change of elementst
mov [esi], edx
add esi, 3 ;move to next byte from first
sub edi, row_bytes ;move to next element from last
cmp edi, esi ;if they are equal then we finished outer lines
jne changebyte
;we proceed with next lines&collumns
mov esi, img_line
add esi, row_bytes
mov img_line, esi
mov edi, img_collumn
sub edi, 3
mov img_collumn, edi
cmp edi, esi
jne changebyte
; eeax is again width of pixel array
mov eax, width
mov img_width, eax
mov esi, img
mov img_line, esi
settt:
mov eax, width
sub eax, 1
lea edi, [eax+eax*2]
add edi, esi
invertbyte:
; horizontal mirror
mov eax, [esi]
mov edx, [edi]
mov ebx, eax
mov ecx, edx
and eax, 00ffffffh
and edx, 00ffffffh
and ebx, 0ff000000h
and ecx, 0ff000000h
or eax, ecx
or edx, ebx
;changing one lines
mov [edi], eax
mov [esi], edx
add esi, 3
sub edi, 3
cmp edi, esi
ja invertbyte
;jump to next lines
mov esi, img_line
add esi, row_bytes
mov img_line, esi
mov ecx, img_width
dec ecx
mov img_width, ecx
jnz settt
; epilogue
pop edi
pop esi
pop ebx
; return to caller
mov esp, ebp
pop ebp
ret
Code for 64bit processor:
; 17. void rotbmp24(void *r9, int width);
; Rotate a 24 bpp square .BMP image of any size 90 degrees clockwise.
;section .data
;message:
; db 'Hello, World', 10, 0
;global rotbmp24
;section .text
;define addresses of parameters passed by caller
;rdi - r9 img [rbp+8] pointer to bmp image
;rsi - r10 width [rbp+12] ;address of width
; allocation of place in memory for local variables
;r11 row_bytes [rbp-4]
;r12 r9_line [rbp-8]
;r13 r9_collumn [rbp-12]
;r14 r9_width [rbp-16]
rotbmp24:
; making stack frame
push rbp
mov rbp, rsp
;sub rsp, 16
; prologue
push rbx
push rsi
push r9
push r10
push r11
push r12
push r14
push r15
mov r9, rdi
mov r10, [rsi]
; calculate row size
mov rax, r10 ; row size in pixels
mov edx, r10d ;preserve rax
imul edx, 3 ; row size* in bytes (3 bytes per pixel)
add edx, 3 ; 3 is the maximum value to fit on 2 least sign. bits
and edx, 0xfffffffc ; zero out 2 least sign. bits, to round up to multiple of 4
mov r11d, edx ; row size in bytes (multiple of 4)
; r14 variable is now width of our bmp image
mov r14, rax
; pixel line
mov rsi, r9
mov r12, rsi
; pixel collumn
sub rax, 1
mov rdi, rax ;preserve rax
imul rdi, 3 ; row size* in bytes (3 bytes per pixel)
mul qword r11 ; rax=rax* (r11, set to 32b)
add rdi, r9
add rdi, rax
mov r13, rdi ;last row
;mov rdi, message ; rdi gets the first argument (a pointer)
;xor rax, rax call
;ret printf ; printf has a variable number of arguments,
; so rax needs to be set to the number of
; vector registers used...zero in this case
changebyte:
; change rows into collumns
mov eax, [rsi] ;first element
mov edx, [rdi] ;last row element
mov ecx, eax ;duplicate them
mov r15d, edx
and eax, 00ffffffh ;get 24 bits and leave rest untouched
and edx, 00ffffffh
and ecx, 0ff000000h
and r15d, 0ff000000h
or eax, r15d ;put bits together
or edx, ecx
mov [rdi], eax ;change of elements
mov [rsi], edx
add rsi, 3 ;move to next byte from first
sub rdi, r11 ;move to next element from last
cmp rdi, rsi ;if they are equal then we finished outer lines
jne changebyte
;we proceed with next lines&collumns
mov rsi, r12
add rsi, r11
mov r12, rsi
mov rdi, r13
sub rdi, 3
mov r13, rdi
cmp rdi, rsi
jne changebyte
; erax is again width of pixel array
mov rax, r10
mov r14, rax
mov rsi, r9
mov r12, rsi
settt:
mov rax, r10
sub rax, 1
lea rdi, [rax+rax*2]
add rdi, rsi
invertbyte:
; horizontal mirror
mov eax, [r9]
mov edx, [rdi]
mov ecx, eax
mov r15d, edx
and eax, 00ffffffh
and edx, 00ffffffh
and ecx, 0ff000000h
and r15d, 0ff000000h
or eax, r15d
or edx, ecx
;changing one lines
mov [rdi], eax
mov [rsi], edx
add rsi, 3
sub rdi, 3
cmp rdi, rsi
ja invertbyte
;jump to next lines
mov rsi, r12
add rsi, r11
mov r12, rsi
mov r15d, r14d
dec r15d
mov r14d, r15d
jnz settt
; epilogue
pop rbp
mov rbp, rsp
sub rsp, 16
pop r15
pop r14
pop r12
pop r11
pop r10
pop r9
pop rsi
pop rbx
; return to caller
mov rsp, rbp
pop rbp
ret
mov r10, [rsi]
should just be mov r10, rsi
since rsi
has the width and is not a pointer.
The three lines at the label epilogue
should be deleted.
With these changes it doesn't blow up for the test case I have tried.
You should really learn to debug yourself.