2

I am trying to add several pixels together in order to do a blurr filter in NASM. I've managed to add three pixels with the value of 00 + d3 + d8 (0 + 211 + 216). When I try to add one more pixel, with the value of 0, the program cannot print the value of the variable blurr.

Update:
It seems that adding to the variable sum can be done at max three times, since if I comment out another add, the value will be printed in my output file.

blurrTopRow:
    ;from 0 - 251 there will be no pixels above the active pixel

    ;set ah to 0 to be sure that no other values changes the byte
    ;save byte in al, ax should be [0000](ah) value(al)
    mov ah, byte 0
    mov al, byte [info + 0]

    ;store sum all pixels in sum, divition will be done here
    add [sum], ax

    ;add pixel beside it (1)
    ;mov ah, byte 0
    mov al, byte [info + 1]

    ;add the value to sum
    ;add [sum], ax    If i add this value, the program stops working

    ;add the pixels below the first pixel
    ;move data to the first 8-bits
    mov ah, 0
    mov al, byte [info + 251]
    add [sum], ax

    ;set the last 8-bits in the 16-bit register (ax) to 0
    ;to avoid messing up the value
    mov ah, 0
    mov al, byte [info + 252]
    add [sum], ax

    ;devide the digit with 4
    mov eax, 0 
    mov ax, [sum]

    mov ebp, 4 
    mov edx, 0
    idiv ebp

    mov [blurr], al

    ret

I believe this is due to some byte error or effective addressing that I do not understand yet. If you want to see all my code, you can find it in pastebin

For the moment, I am super confused why adding a 0 in my sum breaks the program, especially when I've already done this in the code above.

best
Seb

Sep Roland
  • 33,889
  • 7
  • 43
  • 76
  • 2
    _"does not execute correctly and break"_ is not a good problem description. What happens and what does the debugger say? – Jester Sep 01 '17 at 12:03
  • The program prints out 2 bytes, that is stored in the [blurr] variable. No value will be saved in the file when I use the ADD description for the fourth time. (I resentlly found out about this, will change the problem description) I have not tried the debugger yet, I will look into it soon, just need to take some air and sooth my frustration abit xD – Sebastian Lundgren Sep 01 '17 at 12:06
  • It definitely can't print 2 bytes since you pass 1 as argument. Anyway, how did you check nothing is output, and what's your input file? What did you find out with the debugger? – Jester Sep 01 '17 at 12:12
  • thanks for your feedback Jester, you are correct, I print a byte. I check by using the xxd function in shell. When I add the fourth ADD instruction, my program fails to print the value of sum in the file. I will now look into the debugger, I do not know how to use it, but I will try using it and see what it says, I will return. – Sebastian Lundgren Sep 01 '17 at 12:34
  • Ok, I tried using the gdb debugger, and the result I get is the following: Inferior 1 (process 9758) exited with code 0357. Will google around, I do not know what this means :S – Sebastian Lundgren Sep 01 '17 at 12:57
  • Just means that you forgot to set an exit code in your `exitProg` so whatever was in `bl` is the exit code. That's not an error as such. – Jester Sep 01 '17 at 13:00
  • I tried commenting out the division part, and this works, the output is AB, answer should be (1AB) but since I store the value in a byte, this value does not fit, therefore it prints AB. So my guess now, is that the division mess up the register somehow after altering the sum variable? I am playing the guessing game xD – Sebastian Lundgren Sep 01 '17 at 13:41
  • It seems like the instruction mov eax, 0 makes something horrible to the code, my intent is to make sure that the full 32-bit register is 0000 0000 0000 0000 0000 0000 0000 0000 so when I commented this out, it works adding all the variables and do the division. I still do not understand why and how am I afraid – Sebastian Lundgren Sep 01 '17 at 13:45
  • `idiv` is a very slow way to divide by 4. I assume your numbers are actually unsigned, since you zero edx instead of using `cdq` to sign-extend `eax` into `edx:eax`. So you can just `shr eax,2`. See https://stackoverflow.com/questions/40354978/why-is-this-c-code-faster-than-my-hand-written-assembly-for-testing-the-collat/40355466#40355466 – Peter Cordes Sep 01 '17 at 18:48

1 Answers1

3

I have an idea - I'm not sure if it is correct:

In your program you call "open" two times. One time you commented out the mov ecx, ...; the other time the ecx register has never been set at all:

openFileIn:
    mov eax, 5
    mov ebx, fileName
    ; <-- Here you are trusting Linux that ecx=0 on program start
    ;     This is not guaranteed;
    ;     it may change in future Linux versions!
    mov edx, 0777
    int 0x80
    mov [fd_in], eax
    ret

openFileOut:
    mov eax, 5
    mov ebx, outName
    ;mov ecx, 1   <-- why did you comment this out?
    ;                 Maybe "1" is not the correct value!
    mov edx, 0777
    int 0x80

In anoter line you write some address to the ecx register:

readFromFileIn:
    mov eax, 3
    mov ebx, [fd_in]
    mov ecx, info       ; <-- Here
    mov edx, IMAGE_SIZE
    int 0x80
    ret

When you add instructions to your code the addresses of elements in the program may change - including the address of info.

I suspect that without the additional instruction the address of info is a valid parameter for the "open" system call by chance while after inserting the instruction the address is no longer a valid parameter for "open".

You could test this by running both variants of the program with the strace tool which shows you which system calls are called with wich parameters.

Martin Rosenau
  • 17,897
  • 3
  • 19
  • 38
  • That did it, now I can add move data into sum without messing out the output. So it was my filehandler that caused all this mess. So the reason why the code behave so stange was because I was was careless in the filehandler description! Many thanks Martin, it works! I can add more pixels and such without any strange behavior! – Sebastian Lundgren Sep 01 '17 at 19:18