Witam, mam problem związany z assemblerem. Na studiach uczę się assemblera, ale stanąłem pod ściana. dostałem zadanie, które polega na wczytaniu obrazu przy pomocy assemblera i c++. Chciałem wczytać obraz za pomocą c++, następnie przekazać parametry obrazu do assemblera i następnie znowu pokazać wczytany obraz bo przejściu przez assemblera. Mam problem z kodem, nie potrafię wczytać odpowiednio pikseli, jest to może problem z przekazywaniem obrazu bądź też z samym kodem assemblera. Obraz który zwraca mi program odpaleniu go jest "pusty".
Mam trzy pliki:
c++
masm
dll (tylko do przekazania metod)
Za każdą pomoc dziękuje :)
#include <opencv2/opencv.hpp>
#include <iostream>
extern "C" int _fastcall processImage(const unsigned char* inputBuffer, int width, int height, int channels, unsigned char* outputBuffer, int stride);
int main() {
const char* imagePath = "C:/obraz.jpg";
cv::Mat image = cv::imread(imagePath, cv::IMREAD_COLOR);
if (image.empty()) {
std::cerr << "Error: Could not load the image!" << std::endl;
return -1;
}
cv::Mat outputImage(image.size(), image.type());
if (!outputImage.data) {
std::cerr << "Error: Could not allocate memory for output buffer!" << std::endl;
return -1;
}
int stride = image.cols * image.channels();
int result = processImage(
image.data, // Input buffer
image.cols, // Image width
image.rows, // Image height
image.channels(), // Number of channels (e.g., 3 for RGB)
outputImage.data, // Output buffer
stride // Stride (width * channels)
);
if (result != 0) {
std::cerr << "Error: Assembly function failed!" << std::endl;
return -1;
}
cv::imshow("Output Image", outputImage);
cv::waitKey(0);
return 0;
}
;.586
;.MODEL FLAT, C
.DATA
.CODE
; Set up to load image data and apply a filter (convolution)
; rcx - input image pointer (pixels)
; rdx - output image pointer (pixels)
; r8 - filter pointer (kernel)
; r9 - current byte index (pixel index)
; rsp+40 - stride (width of the image in bytes)
; Purpose of registers:
; r10 - used for iterating through the kernel convolution
; r11 - number of bytes left to process
processImage proc export
; Load the amount of bytes to process
MOV R11, [RSP+40] ; Amount of bytes left to process
SUB R11, 8 ; Adjust the byte count (account for stride)
NextPixel:
MOV R10, R9 ; Set R10 to the current pixel index (center)
SUB R10, [RSP+40] ; Adjust to the top middle pixel
SUB R10, 4 ; Adjust to top-left pixel
; Load 3x3 matrix of color-coded pixels into xmm registers
PMOVZXBD xmm0, [RCX+R10] ; Top-left
PMOVZXBD xmm1, [RCX+R10+4] ; Top-middle
PMOVZXBD xmm2, [RCX+R10+8] ; Top-right
ADD R10, [RSP+40] ; Move to the next line (stride)
PMOVZXBD xmm3, [RCX+R10] ; Middle-left
PMOVZXBD xmm4, [RCX+R10+4] ; Middle
PMOVZXBD xmm5, [RCX+R10+8] ; Middle-right
ADD R10, [RSP+40] ; Move to the next line (stride)
PMOVZXBD xmm6, [RCX+R10] ; Bottom-left
PMOVZXBD xmm7, [RCX+R10+4] ; Bottom-middle
PMOVZXBD xmm8, [RCX+R10+8] ; Bottom-right
; Apply the filter (multiply each pixel by the filter value)
PMOVSXBD xmm9, [R8] ; Load filter value
VPBROADCASTD xmm9, xmm9 ; Broadcast filter value to all positions
PMULLD xmm0, xmm9 ; Multiply top-left pixel by filter
PMOVSXBD xmm9, [R8+4] ; Load next filter value
VPBROADCASTD xmm9, xmm9 ; Broadcast filter value
PMULLD xmm1, xmm9 ; Multiply top-middle pixel by filter
PMOVSXBD xmm9, [R8+8] ; Load next filter value
VPBROADCASTD xmm9, xmm9 ; Broadcast filter value
PMULLD xmm2, xmm9 ; Multiply top-right pixel by filter
; Repeat for other pixels in the filter (left to right, top to bottom)
PMOVSXBD xmm9, [R8+12]
VPBROADCASTD xmm9, xmm9
PMULLD xmm3, xmm9
PMOVSXBD xmm9, [R8+16]
VPBROADCASTD xmm9, xmm9
PMULLD xmm4, xmm9
PMOVSXBD xmm9, [R8+20]
VPBROADCASTD xmm9, xmm9
PMULLD xmm5, xmm9
PMOVSXBD xmm9, [R8+24]
VPBROADCASTD xmm9, xmm9
PMULLD xmm6, xmm9
PMOVSXBD xmm9, [R8+28]
VPBROADCASTD xmm9, xmm9
PMULLD xmm7, xmm9
PMOVSXBD xmm9, [R8+32]
VPBROADCASTD xmm9, xmm9
PMULLD xmm8, xmm9
; Sum the components of the pixels (add the results of the multiplications)
PADDD xmm0, xmm1
PADDD xmm0, xmm2
PADDD xmm0, xmm3
PADDD xmm0, xmm4
PADDD xmm0, xmm5
PADDD xmm0, xmm6
PADDD xmm0, xmm7
PADDD xmm0, xmm8
; Check if the pixel value is between 0 and 255 (clamp to this range)
Blue:
MOVD EAX, xmm0
CMP EAX, 255
JG BlueGreater
CMP EAX, 0
JL BlueLesser
Green:
MOV [RDX+R9], AL ; Store the result (Blue component)
PSRLDQ xmm0, 4 ; Shift the next component (Green)
MOVD EAX, xmm0
CMP EAX, 255
JG GreenGreater
CMP EAX, 0
JL GreenLesser
Red:
MOV [RDX+R9+1], AL ; Store the result (Green component)
PSRLDQ xmm0, 4 ; Shift the next component (Red)
MOVD EAX, xmm0
CMP EAX, 255
JG RedGreater
CMP EAX, 0
JL RedLesser
Alpha:
MOV [RDX+R9+2], AL ; Store the result (Red component)
MOV EAX, 255
MOV [RDX+R9+3], AL ; Set the Alpha component to 255
ADD R9, 4
SUB R11, 4
CMP R11, 0 ; Check if there are more bytes to process
JNE NextPixel
ret
BlueGreater:
MOV AL, 255 ; Set Blue to 255 if it's greater
JMP Green
BlueLesser:
MOV AL, 0 ; Set Blue to 0 if it's less
JMP Green
GreenGreater:
MOV AL, 255 ; Set Green to 255 if it's greater
JMP Red
GreenLesser:
MOV AL, 0 ; Set Green to 0 if it's less
JMP Red
RedGreater:
MOV AL, 255 ; Set Red to 255 if it's greater
JMP Alpha
RedLesser:
MOV AL, 0 ; Set Red to 0 if it's less
JMP Alpha
processImage endp
END
.