Assembly function on strings - string

I made function which should return the number of the highest sequence of the same character in a string. So in case of string 'aabbbcaaaabbccc' it should be 4, in case of 'aaaaa' it should be 5. So for 'aaaaa' this function should return 5, actually it returns 2. I am staring on it long time, but I can't see a mistake.
unsigned long najdlhsia(const char *vstup) {
__asm {
mov eax, 0
mov ecx, 0
mov ebx, vstup
cmp [ebx], 0
je k
mov edx, [ebx]
add ebx, 1
inc eax
inc ecx
c: cmp byte ptr[ebx], 0
je p
cmp [ebx], edx
jne a1
inc ecx
add ebx, 1
jmp c
a1: cmp ecx, eax
jng a2
mov eax, ecx
a2: mov ecx, 1
mov edx, [ebx]
add ebx, 1
jmp c
p: cmp ecx, eax
jng k
mov eax, ecx
k:
}
}
int main()
{
printf("%d", najdlhsia("aaaaa"));
return 0;
}

Related

How to find characters in a string Assembly x86?

I'm trying to rewrite the C code below in Assembly x86
int myFn( char * v, char c, int size ) {
int i;
for(i=0; i < size; i++ )
if( v[i] == c )
return i;
return -1;
}
I've tried to use this code in x86:
myFn:
mov esi, 0
mov ebx, [esp + 8]
mov ecx, [esp + 12]
FOR:
mov eax, -1
cmp esi, [esp + 4]
jge ENDFOR
cmp [ecx + esi], ebx
je EQUAL
inc esi
jmp FOR
EQUAL:
mov eax, [esi]
ENDFOR:
ret
I've also created this program to test the function:
section .data
fmt: db "strfind: %d", 10, 0
str: db "test", 0
section .text
global main
extern printf
main:
mov eax, 's'
mov ebx, 4
push str
push eax
push ebx
call myFn
add esp, 12
push eax
push fmt
call printf
add esp, 8
ret
myFn:
mov esi, 0
mov ebx, [esp + 8]
mov ecx, [esp + 12]
FOR:
mov eax, -1
cmp esi, [esp + 4]
jge ENDFOR
cmp [ecx + esi], ebx
je EQUAL
inc esi
jmp FOR
EQUAL:
mov eax, [esi]
ENDFOR:
ret
I'm getting Segmentation Fault error or the wrong result when trying to test it. I believe the problem is when comparing the character of the string with the character I want to find

Segmentation issue NASM

I'm working on conversions of c programs to NASM and I've been having issues with segmentation faults after the program runs. It will do what its supposed to do but will provide a segmentation fault message at the end of it.
The code is:
segment .data
out_less db "Z is less than 20.", 10, 0
out_greater db "Z is greater than 20.", 10, 0
out_equal db "Z is equal to 20! Yeah Z!", 10, 0
segment .bss
segment .text
global main
extern printf
ret
main:
mov eax, 10
mov ebx, 12
mov ecx, eax
add ecx, ebx ;set c (ecx reserved)
mov eax, 3
mov ebx, ecx
sub ebx, eax ;set f (ebx reserved)
mov eax, 12
mul ecx
add ecx, 10 ;(a+b*c) (ecx reserved)
mov eax, 6
mul ebx
mov eax, 3
sub eax, ebx
mov ebx, eax ;(d-e*f) (ebx reserved) reassign to ebx to keep eax open for manipulation
mov eax, ecx
div ebx
mov ecx, eax
add ecx, 1 ;(a+b*c)/(d-e*f) + 1
cmp ecx, 20
jl less
jg greater
je equal
mov eax, 0
ret
less:
push out_less
call printf
ret
jmp end
greater:
push out_greater
call printf
ret
jmp end
equal:
push out_equal
call printf
ret
jmp end
end:
mov eax, 0
ret
I'm not sure whats causing the fault because the program does actually run correctly any thoughts?
Thanks!
Update - this seems to work:
segment .data
out_less db "Z is less than 20.", 10, 0
out_greater db "Z is greater than 20.", 10, 0
out_equal db "Z is equal to 20! Yeah Z!", 10, 0
segment .bss
segment .text
global main
extern printf
main:
mov eax, 10
mov ebx, 12
mov ecx, eax
add ecx, ebx ;set c (ecx reserved)
mov eax, 3
mov ebx, ecx
sub ebx, eax ;set f (ebx reserved)
mov eax, 12
mul ecx
add ecx, 10 ;(a+b*c) (ecx reserved)
mov eax, 6
mul ebx
mov eax, 3
sub eax, ebx
mov ebx, eax ;(d-e*f) (ebx reserved) reassign to ebx to keep eax open for manipulation
mov eax, ecx
div ebx
mov ecx, eax
add ecx, 1 ;(a+b*c)/(d-e*f) + 1
cmp ecx, 20
jl less
jg greater
jmp equal
less:
push out_less
call printf
add esp,4
jmp exit
greater:
push out_greater
call printf
add esp,4
jmp exit
equal:
push out_equal
call printf
add esp,4
exit:
mov eax, 0
ret
end

Assembly language and printing result. Fibbonacci sequence

I use Assembly on x86 Linux, with instructions for Intel 8086. I have a problem with my program, which should count the element of Fibbonacci sequence.
This program I run with args, for e.g.:
./fibb 1 2 3 ,
what means: 1st element of sequence is 1, the 2st element is 2 and we want to get the 3rd.
And that example works great, but when I try to run like:
./fibb 1 2 4 ,
then I've got some junk.
Please help me. I'm new in Assembly so please explain me clearly what I'm doing wrong.
Here is my code:
.intel_syntax noprefix
.global _start
.data
var1:
.ascii "To few args\n"
.equ len1, $-var1
var2:
.ascii "Wrong data\n"
.equ len2, $-var2
var3:
.ascii "wrong element of the sequence\n"
.equ len3, $-var3
var4:
.ascii "element of the sequence is higher than 255\n"
.equ len4, $-var4
var5:
.ascii "result: "
.equ len5, $-var5
var6:
.byte 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
var7:
.byte 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
var8:
.byte 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
.text
_start:
jmp ety5
ety1:
mov bh, 48
ety2:
cmp [eax], bh
jz ety3
inc bh
cmp bh, 58
jnz ety2
ety3:
cmp bh, 58
jnz ety4
inc bl
ety4:
inc eax
cmp [eax], byte ptr 0
jnz ety1
ret
ety5:
jmp ety10
invert:
xor ecx, ecx
ety6:
inc ebx
inc ecx
cmp [ebx], byte ptr 0
jnz ety6
ety7:
dec ecx
cmp ecx, 0
jz ety8
mov [ebx], byte ptr 0
dec ebx
cmp [ebx], byte ptr 48
jz ety7
inc ebx
ety8:
inc ecx
push ecx
xor ecx, ecx
ety9:
add ecx, 2
push ecx
dec ebx
mov cl, [eax]
mov ch, [ebx]
mov [eax], ch
mov [ebx], cl
inc eax
pop ecx
cmp ecx, [ebp-8]
jb ety9
pop ecx
ret
ety10:
jmp ety18
ety11:
mov cl, [eax]
cmp cl, 0
jz ety12
sub cl, 48
ety12:
mov ch, [ebx]
sub ch, 48
add cl, dh
xor dh, dh
add cl, ch
cmp cl, 10
jb ety13
inc dh
sub cl, 10
ety13:
add cl, 48
mov [eax], cl
inc eax
inc ebx
cmp [ebx], byte ptr 0
jnz ety11
ety14:
cmp [eax], byte ptr 0
jz ety16
mov cl, [eax]
sub cl, 48
add cl, dh
xor dh, dh
cmp cl, 10
jb ety15
sub cl, 10
inc dh
ety15:
add cl, 48
mov [eax], cl
inc eax
jmp ety14
ety16:
cmp dh, 0
jz ety17
add dh, 48
mov [eax], dh
ety17:
ret
ety18:
jmp ety22
ety19:
mov esi, 3
mov dl, [ecx]
sub dl, 48
loop_mul:
add dl, dl
dec esi
cmp esi,0
jnz loop_mul
add dl, dh
xor dh, dh
cmp dl, 10
jb ety20
sub dl,10
inc dh
ety20:
add dl, 48
mov [ebx], dl
inc ebx
inc ecx
cmp [ecx], byte ptr 0
jnz ety19
cmp dh, 0
jz ety21
add dh, 48
mov [ebx], dh
ety21:
mov ebx, offset var8
ret
ety22:
mov ebp, esp
mov eax, [ebp+8]
cmp eax, 0
jnz ety23
mov eax, 4
mov ebx, 1
mov ecx, offset var1
mov edx, offset len1
int 0x80
mov eax, 1
mov ebx, 0
int 0x80
ety23:
mov eax, [ebp+12]
cmp eax, 0
jnz ety24
mov eax, 4
mov ebx, 1
mov ecx, offset var1
mov edx, offset len1
int 0x80
mov eax, 1
mov ebx, 0
int 0x80
ety24:
mov eax, [ebp+16]
cmp eax, 0
jnz ety25
mov eax, 4
mov ebx, 1
mov ecx, offset var1
mov edx, offset len1
int 0x80
mov eax, 1
mov ebx, 0
int 0x80
ety25:
xor bl, bl
mov eax, [ebp+8]
call ety1
mov eax, [ebp+12]
call ety1
cmp bl, 0
jz ety26
mov eax, 4
mov ebx, 1
mov ecx, offset var2
mov edx, offset len2
int 0x80
mov eax, 1
mov ebx, 0
int 0x80
ety26:
mov eax, [ebp+16]
call ety1
cmp bl, 0
jz ety27
mov eax, 4
mov ebx, 1
mov ecx, offset var3
mov edx, offset len3
int 0x80
mov eax, 1
mov ebx, 0
int 0x80
ety27:
xor ebx, ebx;
mov eax, [ebp+16]
mov ecx, [ebp+16]
ety28:
cmp [eax], byte ptr 0
jnz ety29
mov eax, 4
mov ebx, 1
mov ecx, offset var3
mov edx, offset len3
int 0x80
mov eax, 1
mov ebx, 0
int 0x80
ety29:
cmp [eax], byte ptr 48
jnz ety30
inc eax
inc ecx
jmp ety28
ety30:
inc ecx
cmp [ecx], byte ptr 0
jz ety35
inc ecx
cmp [ecx], byte ptr 0
jz ety33
inc ecx
cmp [ecx], byte ptr 0
jz ety31
mov eax, 4
mov ebx, 1
mov ecx, offset var4
mov edx, offset len4
int 0x80
mov eax, 1
mov ebx, 0
int 0x80
ety31:
mov cl, [eax]
inc eax
sub cl, 48
ety32:
add ebx, 100
dec cl
cmp cl, 0
jnz ety32
ety33:
mov cl, [eax]
inc eax
sub cl, 48
cmp cl, 0
jz ety35
ety34:
add ebx, 10
dec cl
cmp cl, 0
jnz ety34
ety35:
mov cl, [eax]
sub cl, 48
cmp cl, 0
jz ety37
ety36:
inc ebx
dec cl
cmp cl, 0
jnz ety36
ety37:
cmp ebx, 256
jb ety38
mov eax, 4
mov ebx, 1
mov ecx, offset var4
mov edx, offset len4
int 0x80
mov eax, 1
mov ebx, 0
int 0x80
ety38:
xor dl, dl
ety39:
dec ebx
inc dl
cmp ebx,0
jnz ety39
mov eax, [ebp+12]
mov ebx, offset var7
xor dh, dh
ety40:
inc eax
inc dh
cmp [eax], byte ptr 0
jnz ety40
xor ch, ch
ety41:
dec eax
dec dh
mov cl, [eax]
mov [ebx], cl
inc ebx
cmp dh, 0
jnz ety41
mov eax, [ebp+8]
mov ebx, offset var6
ety42:
inc eax
inc dh
cmp [eax], byte ptr 0
jnz ety42
ety43:
dec eax
dec dh
mov cl, [eax]
mov [ebx], cl
inc ebx
cmp dh, 0
jnz ety43
cmp dl, 1
jnz ety44
jmp ety46
ety44:
dec dl
cmp dl, 1
jnz ety45
jmp ety47
ety45:
dec dl
cmp dl, 0
jz ety47
push edx
xor dh, dh
mov eax, offset var6
mov ebx, offset var8
mov ecx, offset var7
call ety19
xor dh, dh
call ety11
pop edx
dec dl
cmp dl, 0
jz ety46
push edx
xor dh, dh
mov eax, offset var7
mov ebx, offset var8
mov ecx, offset var6
call ety19
xor dh, dh
call ety11
pop edx
jmp ety45
ety46:
mov eax, 4
mov ebx, 1
mov ecx, offset var5
mov edx, offset len5
int 0x80
mov eax, offset var6
mov ebx, offset var6
call invert
mov eax, 4
mov ebx, 1
mov edx, ecx
mov ecx, offset var6
int 0x80
mov eax, 4
mov ebx, 1
mov [ecx], byte ptr 10
mov edx, 1
int 0x80
mov eax, 1
mov ebx, 0
int 0x80
ety47:
mov eax, 4
mov ebx, 1
mov ecx, offset var5
mov edx, offset len5
int 0x80
mov eax, offset var7
mov ebx, offset var7
call invert
mov eax, 4
mov ebx, 1
mov edx, ecx
mov ecx, offset var7
int 0x80
mov eax, 4
mov ebx, 1
mov [ecx], byte ptr 10
mov edx, 1
int 0x80
mov eax, 1
mov ebx, 0
int 0x80
int 0x80
This code supposedly fills EAX with the first parameter (a number, not an address).
mov eax, [ebp+8]
call ety1
But at ety1 this code compares the byte at the address EAX with BH.
ety1:
mov bh, 48
ety2:
cmp [eax], bh
jz ety3
How is that going to work?
EDIT
By the time I arrived at the real entry point of this program through a ridiculously long cascade of jumps I totally forgot that this is in fact an application and not just some subroutine. Parameters are thus addresses rendering my answer void!
EDIT2
Are you sure the DS register is properly initialized?

IDA PRO Struct Pointer Counter big number not starting from address offset 0, Lowers a bit slightly but not completely to 0

I put the whole question in 3 images from research it seems I need to use CTRL+R but I don't think that's what I need since I could lower the number a bit lower just can't lower it to the proper amount of 0.
I think the problem is I'm not creating the structs properly probably missing something.
ASM Code:
.text:0040E040 ; =============== S U B R O U T I N E =======================================
.text:0040E040
.text:0040E040
.text:0040E040 ; struct_ARENA *__thiscall code(struct_PLAYER *player, const void *buf, unsigned int len, int a4)
.text:0040E040 sub_40E040 proc near
.text:0040E040
.text:0040E040
.text:0040E040 buf = dword ptr 4
.text:0040E040 len = dword ptr 8
.text:0040E040 a4 = dword ptr 0Ch
.text:0040E040
.text:0040E040 push ebx
.text:0040E041 push esi
.text:0040E042 mov esi, ecx
.text:0040E044 mov eax, [esi+1Ch]
.text:0040E047 test eax, eax
.text:0040E049 jz short loc_40E093
.text:0040E04B mov ecx, [eax+0FF0Ch]
.text:0040E051 xor ebx, ebx
.text:0040E053 test ecx, ecx
.text:0040E055 jle short loc_40E093
.text:0040E057 push edi
.text:0040E058 push ebp
.text:0040E059 mov ebp, [esp+10h+a4]
.text:0040E05D mov edi, 0FB20h
.text:0040E062
.text:0040E062 loc_40E062:
.text:0040E062 mov eax, [edi+eax]
.text:0040E065 cmp eax, esi
.text:0040E067 jz short loc_40E082
.text:0040E069 mov ecx, [eax+38h]
.text:0040E06C test ecx, ecx
.text:0040E06E jnz short loc_40E082
.text:0040E070 mov ecx, [esp+10h+len]
.text:0040E074 mov edx, [esp+10h+buf]
.text:0040E078 push ebp ; a4
.text:0040E079 push ecx ; len
.text:0040E07A push edx ; buf
.text:0040E07B mov ecx, eax ; this
.text:0040E07D call SendPlayerReliablePacket
.text:0040E082
.text:0040E082 loc_40E082:
.text:0040E082
.text:0040E082 mov eax, [esi+1Ch]
.text:0040E085 inc ebx
.text:0040E086 add edi, 4
.text:0040E089 cmp ebx, [eax+0FF0Ch]
.text:0040E08F jl short loc_40E062
.text:0040E091 pop ebp
.text:0040E092 pop edi
.text:0040E093
.text:0040E093 loc_40E093:
.text:0040E093
.text:0040E093 pop esi
.text:0040E094 pop ebx
.text:0040E095 retn 0Ch
.text:0040E095 sub_40E040 endp
.text:0040E095 ; ---------------------------------------------------------------------------
.text:0040E098 align 10h
Here is one that looks better only 1 struct instead of 2 but still same problem

NASM JLE: Jump if Less or Equal always evaluating to true

I have code here that reads in input to determine the dimensions of a matrix/2d array and then reads in numbers one by one. Then it is SUPPOSED to spit out the smallest number.
However my comparison operator doesn't seem to be working? I've tried putting both as registers, with different variables and so on but for some reason eax with whatever happened to be the first entry in the array is ALWAYS smaller than the next number, even if this is clearly not the case.
So it always skips reassignment.
Code: Just skip straight to cmp eax,[num]
My guess is something is causing num, perhaps how its declared? Is always 'larger' than eax, is there extra fluff I am not aware of?
segment .bss
num: resw 1 ;For storing a number, to be read of printed....
nod: resb 1 ;For storing the number of digits....
temp: resb 2
matrix1: resw 200
m: resw 1
n: resw 1
i: resw 1
j: resw 1
small: resb 4 ; temp variable
buff resb 4
segment .data
msg1: db "Enter the number of rows in the matrix : "
msg_size1: equ $-msg1
msg2: db "Enter the elements one by one(row by row) : "
msg_size2: equ $-msg2
msg3: db "Enter the number of columns in the matrix : "
msg_size3: equ $-msg3
msg4: db "The Smallest Number is... : "
msg_size4: equ $-msg4
tab: db 9 ;ASCII for vertical tab
new_line: db 10 ;ASCII for new line
segment .text
global _start
_start:
;; code for reading number of rows and columns, this works fine.
mov eax, 4
mov ebx, 1
mov ecx, msg1
mov edx, msg_size1
int 80h
;; read in rows
mov ecx, 0
call read_num
mov cx, word[num]
mov word[m], cx
mov eax, 4
mov ebx, 1
mov ecx, msg3
mov edx, msg_size3
int 80h
;; read in columns
mov ecx, 0
call read_num
mov cx, word[num]
mov word[n], cx
mov eax, 4
mov ebx, 1
mov ecx, msg2
mov edx, msg_size2
int 80h
;; Reading in each element and storing it into the array
mov esi, 0
mov ebx, matrix1
;; init loop
mov word[i], 0
mov word[j], 0
;; Outer loop
i_loop:
mov word[j], 0
;; Inner Loop
j_loop:
;; A function
call read_num
;; Result of that function is now stored int he matrix
mov dx , word[num]
mov word[ebx + 2 * esi], dx
inc esi ;Incrementing array index by one....
inc word[j]
mov cx, word[j]
cmp cx, word[n]
jb j_loop
;; End Inner Loop
inc word[i]
mov cx, word[i]
cmp cx, word[m]
jb i_loop
;; End Outer Loop
;; Now begins the code to find the smallest number
mov eax, [matrix1]
;; Moves first element of Matrix1 into eax
;;; saves eax into small
mov [small], eax
;Loop through the matrix, check each number if its smaller than the first number in the array. AT the end print said number.
;Reading each element of the matrix.(Storing the elements in row major order).......
mov esi, 0
mov edi, matrix1
;; Reinit loop cters
mov word[i], 0
mov word[j], 0
;; Loop
i_loop2:
mov word[j], 0
j_loop2:
;eax will contain the array index and each element is 2 bytes(1 word) long
mov dx, word[edi+2*esi] ;
mov word[num] , dx
cmp eax,[num] ; compares eax and ebx
jle skip ;if eax is SMALLER than ebx, we can safely skip reassignment
;as our current value is already smallest.
mov eax, [num] ; stores new smallest number if the new number was smaller.
mov [small], eax
;; reassignment code is always skipped.
skip:
inc esi
inc word[j]
mov cx, word[j]
cmp cx, word[n]
jb j_loop2
inc word[i]
mov cx, word[i]
cmp cx, word[m]
jb i_loop2
; code to output the smallest number
;; Some ui text.
mov eax, 4
mov ebx, 1
mov ecx, msg4
mov edx, msg_size4
int 80h
mov ecx, 0
;; Now the actual smallest number
mov eax, 4 ; system_write
mov ebx, 1 ; stdout
mov ecx, [small] ; move smallest element to accumulator
add ecx, 48 ; convert to ascii representation
mov [buff], ecx ; move to memory
mov ecx, buff
mov edx, 4 ; size, 4 bytes
int 80h
exit:
mov eax, 1
mov ebx, 0
int 80h
;Function to read a number from console and to store that in num
read_num:
pusha
mov word[num], 0
loop_read:
mov eax, 3
mov ebx, 0
mov ecx, temp
mov edx, 1
int 80h
cmp byte[temp], 10
je end_read
mov ax, word[num]
mov bx, 10
mul bx
mov bl, byte[temp]
sub bl, 30h
mov bh, 0
add ax, bx
mov word[num], ax
jmp loop_read
end_read:
popa
ret
Oh yes, several hours of fidgeting and seconds after this post I figured out exactly why. Turns out yes, the way I declared "num" yes indeed added in extra information. I changed it to resb 4 and it works.
Crabbaskets.

Resources