آموزش اسمبلی - Assembly

شروع موضوع توسط MnavidM ‏27 سپتامبر 2005 در انجمن منطق و الگوریتم برنامه‌نویسی

وضعیت موضوع:
موضوع بسته شده است.
  1. saalek110

    saalek110 Well-Known Member

    ارسال‌ها:
    2,765
    تشکر شده:
    1,382
    امتیاز دستاورد:
    113
    برنامه گرفتن ساعت كامپيوتر:
    برنامه زير اين طوري نشان مي دهد:
    کد (Text):

    1133-3200-11
     
    كه يعني ساعت 11 و 33 دقيقه و 32 ثانيه است. و 11 ساعت هم از نيمه شب گذشته.
    با تغيير ساعت كامپيوتر خود ببينيد من درست گفتم يا نه.
    در كد قسمتي help همان اموليتوره كه من نقل كردم. اصل برنامه هم اين كده:
    mov ah,2
    int 1ah
    مي توانيد اين دو خط كد را برداريد و باقي اش را خودتان بنويسيد. البته با وقفه هاي ديگر هم فكر كنم ساعت را بشه نمايش داد. خروجي را هم در كدها مي بينيد كه بايد در آن رجيسترها دنبالش بگرديد.

    بقيه برنامه جز اين دو خط كد:
    با احضار زير برنامه bl_print چاپ رجيستره تا ببينيم ساعت چنده. شايد من جاهايي غلط نوشتم . خودتان اصلاح كنيد. . نمي دانم چرا dl تغيير نمي كنه.شايد هم دليلي نداره كه تغيير كنه. چون ثانيه در dh بود و تمام شد ديگه.اين برنامه براي تنوع بود.
    اين تكه هم كه براي چاپ منهاست. براي احتياط رجيستراش را پوش كردم.
    push dx
    push ax
    mov ah,2
    mov dl,'-'
    int 21h
    pop ax
    pop dx

    کد (Text):

    .model small
    .stack
    .data
    .code
    asli proc
    ;---------------------------
    ;INT 1Ah / AH = 00h - get system time.

    ;return:

    ;CX:DX = number of clock ticks since midnight.
    ;AL = midnight counter, advanced each time midnight passes.

    ;Notes:
    ;There are approximately 18.20648 clock ticks per second,
    ;and 1800B0h per 24 hours.
    ;AL is not set by emulator yet!
    ;----------------------
    mov ah,2
    int 1ah

    mov bl,ch
    call bl_print
    mov bl,cl
    call bl_print
    ;------
    push dx
    push ax
    mov ah,2
    mov dl,'-'
    int 21h
    pop ax
    pop dx
    ;------
    mov bl,dh
    call bl_print
    mov bl,dl
    call bl_print
    ;------
    push dx
    push ax
    mov ah,2
    mov dl,'-'
    int 21h
    pop ax
    pop dx
    ;------
    mov bl,al
    call bl_print

    ;---------------------------
    mov ax,4c00h ; return to dos DOS
    int 21h

    asli endp
    ; ============ sub bl_print ===========
    bl_print PROC NEAR
    push ax
    push bx
    push cx
    push dx
    ;----------part 1
    mov ah,2h
    mov dl,bl

    mov cl,04h
    shr dl,cl

    add dl,30h

    cmp dl,3ah
    jl lable1

    add dl,07h

    lable1:
    int 21h

    ; -----------part 2

    mov dl,bl
    and dl,0fh

    add dl,30h

    cmp dl,3ah
    jl lable2

    add dl,07h

    lable2:
    int 21h
    ;------------
    pop dx
    pop cx
    pop bx
    pop ax

    ret ; return to where it was called
    bl_print ENDP
    ;===================================

         end asli
     
    براي تفريح بيشتر من حلقه كردم اول و آخر برنامه را.
    البته براي خروج هم چيزي در نظر نگرفتم. اين تكه را انداختم آخر برنامه:
    ;============
    mov dh,0 ;DH = row.
    mov dl,0 ;DL = column.
    mov ah,2 ;service
    int 10h
    jmp lablexxx
    ;===========
    كه كرزر را مي آورد اول صفحه. و بعد جامپ مي كند به اول برنامه در lablexxx .
    کد (Text):

    .model small
    .stack
    .data
    .code
    asli proc
    ;---------------------------
    ;INT 1Ah / AH = 00h - get system time.

    ;return:

    ;CX:DX = number of clock ticks since midnight.
    ;AL = midnight counter, advanced each time midnight passes.

    ;Notes:
    ;There are approximately 18.20648 clock ticks per second,
    ;and 1800B0h per 24 hours.
    ;AL is not set by emulator yet!
    ;----------------------
    lablexxx:
    mov ah,2
    int 1ah

    mov bl,ch
    call bl_print
    mov bl,cl
    call bl_print
    ;------
    push dx
    push ax
    mov ah,2
    mov dl,'-'
    int 21h
    pop ax
    pop dx
    ;------
    mov bl,dh
    call bl_print
    mov bl,dl
    call bl_print
    ;------
    push dx
    push ax
    mov ah,2
    mov dl,'-'
    int 21h
    pop ax
    pop dx
    ;------
    mov bl,al
    call bl_print
    ;============
    mov dh,0  ;DH = row.
    mov dl,0  ;DL = column.
    mov ah,2  ;service
    int 10h
    jmp lablexxx
    ;===========
    ;---------------------------
    mov ax,4c00h ; return to dos DOS
    int 21h

    asli endp
    ; ============ sub bl_print ===========
    bl_print PROC NEAR
    push ax
    push bx
    push cx
    push dx
    ;----------part 1
    mov ah,2h
    mov dl,bl

    mov cl,04h
    shr dl,cl

    add dl,30h

    cmp dl,3ah
    jl lable1

    add dl,07h

    lable1:
    int 21h

    ; -----------part 2

    mov dl,bl
    and dl,0fh

    add dl,30h

    cmp dl,3ah
    jl lable2

    add dl,07h

    lable2:
    int 21h
    ;------------
    pop dx
    pop cx
    pop bx
    pop ax

    ret ; return to where it was called
    bl_print ENDP
    ;===================================

         end asli

     
    حالا شد شبيه ساعت كامپيوتري. اگر دكمه full screen را در بالاي پنجره داسي بزنيد حركت سريع كرزر را بهتر مي بينيد.
     
    آخرین ویرایش: ‏29 سپتامبر 2019
    نوشته شده توسط saalek110 در ‏8 آوریل 2008
    hamed.rafiee از این پست تشکر کرده است.
  2. saalek110

    saalek110 Well-Known Member

    ارسال‌ها:
    2,765
    تشکر شده:
    1,382
    امتیاز دستاورد:
    113
    من از dh و dl استفاده كردم. و اين دو در دو حلقه خارجي و داخلي در حال افزايش هستند. و در cmp ها به راحتي از ين دو استفاده كردم. شما هم نياز داريد تا 2 رجيستر را در حلقه بيروني و حلقه دروني افزايش دهيد تا در عمق حلقه اين دو ابزار شما باشد. برنامه اي كه نستا براي رسم پيكسل ها نوشت هم ((حلقه اي تو در تو با cx و dx)) بود. در عمق حلقه نستا هم دو ابزار در اختيارش بود. ولي حلقه ((تو در تو فقط با cx )) اشكالش اينه كه در عمق حلقه ما به cx بيروني دسترسي نداريم. چون با push و pop روي حلقه داخلي پل زده ايم.
    پس نمي توانيم در عمق حلقه بفهميم كه الان در كدام رديف هستيم. مگر رجيستري را در حلقه بيروني افزايش دهيد تا در عمق حلقه از آن استفاده كنيد. اگر نخواهيد اين كار را بكنيد بايد برنامه را 3 قسمت كنيد. قسمتي كه رديف اول را مي كشد . برنامه اي كه وسط را مي كشد و برنامه اي كه رديف آخر ستاره ها را رسم مي كند.
    شما با برنامه ((اينتر كننده)) بايستي رجيستري را هم افزايش بدهيد كه بدانيد چند بار اينتر كرده ايد.
    البته اگر منظور شما را درست فهميده باشم.
    = = = = = = = = = ==
    اما راجع به push و pop ها:
    ببينيد ما گاهي از مثلا dl در 10 جاي برنامه مي خواهيم استفاده كنيم. با اين push و pop ها ما برنامه را پارتيشن بندي مي كنيم. برنامه زير را ببينيد:
    Mov ah,2

    Mov dl,33

    Int 21h

    كه كاركتر مربوط به عدد 33 را چاپ مي كند. اگر وسطش يك خطي باشد مثل mov dl,54 يعني اين طوري:

    Mov ah,2
    Mov dl,33

    Mov dl,54

    Int 21h

    خوب معلومه كه 54 را چاپ مي كند نه 33 را. حالا من دو طرف 54 مي ايم push و pop مي گذارم:
    Mov ah,2
    Mov dl,33

    Push dx
    Mov dl,54
    Pop dx

    Int 21h
    حالا ديگه همان 33 چاپ ميشه نه 54 . چون من پل زده ام روي 54.
    منظورم از پل اينه كه قبل دستور 54 مي آيم يك نسخه از dx (شامل dl ) را در پشته كپي مي گيرم و بعد خط 54 مي آيم از آن كپي دوباره dx را ترميم مي كنم.
    من اينجا خلاصه كردم و گفتم چاپ 33 و 54 . مي دانيد كه اولا ما دو مبناي عدد دادن داريم 16 و 10 كه اگر به 16 مي خواهيد بدهيد بايد بعد عدد حرف اچ را بگذاريد و ثانيا از جدول اسكي بايد نگاه كنيد كه وقفه با ديدن 33 و 54 چه كاراكتري را چاپ مي كند.
    = = == = = = =
    تمام زيربرنامه ها بايد رجيسترهايي را كه دستكاري مي كنند را push و pop كنند. مگر اين كه با يك رجيستر بخواهند خروجي بفرستند به برنامه اصلي كه او را صدا كرده. در اين مورد هم فقط آن رجيستر را باز مي گذاريم و بقيه را push و pop مي كنيم.

    نكته مهم: آدرس برگشت زيربرنامه به برنامه اصلي ،يعني شماره خط آن خط كه بلافاصله بعد خطي قرار دارد كه دستور call داخلشه ، در پشته نگهداري ميشه. پس قبل رسيدن به دستور ret يعني بازگشت به برنامه اصلي بايد پشته را خالي كنيد.

    براي راحتي اين طور مي شود گفت كه داخل هر زيربرنامه (يا برنامه اصلي) هر چيزي را كه push كرده ايد ، داخل همان زيربرنامه pop كنيد.
    اين طوري استفاده شما از پشته با استفاده خود cpu از پشته تداخل نخواهد كرد
     
    آخرین ویرایش: ‏29 سپتامبر 2019
    نوشته شده توسط saalek110 در ‏8 آوریل 2008
  3. saalek110

    saalek110 Well-Known Member

    ارسال‌ها:
    2,765
    تشکر شده:
    1,382
    امتیاز دستاورد:
    113
    در صفحات 4 و 5 و 6 تاپيك داشتيم از يك سايت كه در 7 صفحه آموزش داده بود تمرين مي كرديم و صفحه 5 آن سايت را نگفتيم.
    آدرس سايت:
    http://burks.brighton.ac.uk/burks/language/asm/asmtut/asm1.htm

    آدرس صفحه 5 آن:
    http://burks.brighton.ac.uk/burks/language/asm/asmtut/asm6.htm

    = = = = = = = = = = = = =
    حالا كه سرمان خلوت شد كمي ، خوبه كه اونم بگيم. از طرفي شايد بشه با فايل خواني كارهاي جالبي كرد.
    = = = = = == = = = = = =
    چند برنامه در اين سايت است كه كد اولي را در زير مي آورم و با عكسي كه نتيجه اجراي آن است. در عكس فايل را با نت پد مي بينيد و مي بينيد كه نتيجه اجراي برنامه هم دقيقا همان است.
    يادتان نرود قبل اجراي اين برنامه فايل تكستي با نام test در درايو سي بسازيد. يك بار هم بي فايل اجرا كنيد تا خطا را دريافت كنيد.


    a1.jpg

    کد (Text):

    .model small
    .stack
    .code

    mov ax,@data ; base address of data segment
    mov ds,ax ; put this in ds

    mov dx,OFFSET FileName ; put address of filename in dx
    mov al,2 ; access mode - read and write
    mov ah,3Dh ; function 3Dh -open a file
    int 21h ; call DOS service

    mov Handle,ax ; save file handle for later
    jc ErrorOpening ; jump if carry flag set - error!

    mov dx,offset Buffer ; address of buffer in dx
    mov bx,Handle ; handle in bx
    mov cx,100 ; amount of bytes to be read
    mov ah,3Fh ; function 3Fh - read from file
    int 21h ; call dos service

    jc ErrorReading ; jump if carry flag set - error!

    mov bx,Handle ; put file handle in bx
    mov ah,3Eh ; function 3Eh - close a file
    int 21h ; call DOS service

    mov cx,100 ; length of string
    mov si,OFFSET Buffer ; DS:SI - address of string
    xor bh,bh ; video page - 0
    mov ah,0Eh ; function 0Eh - write character

    NextChar:

    lodsb ; AL = next character in string
    int 10h ; call BIOS service
    loop NextChar

    mov ax,4C00h ; terminate program
    int 21h

    ErrorOpening:

    mov dx,offset OpenError ; display an error
    mov ah,09h ; using function 09h
    int 21h ; call DOS service
    mov ax,4C01h ; end program with an errorlevel =1
    int 21h

    ErrorReading:
    mov dx,offset ReadError ; display an error
    mov ah,09h ; using function 09h
    int 21h ; call DOS service
    mov ax,4C02h ; end program with an errorlevel =2
    int 21h

    .data
    Handle DW ? ; to store file handle
    FileName DB "C:\test.txt",0 ; file to be opened
    OpenError DB "An error has occured(opening)!$"
    ReadError DB "An error has occured(reading)!$"
    Buffer DB 100 dup (?) ; buffer to store data

    END
     
    خيلي برنامه جالبي است. و علاوه بر خواندن فايل نكات ديگري هم دارد. يكي از نكاتش اينه كه 3 بار دستور خروج در آن بكار رفته اولي اين است:
    mov ax,4C00h ; terminate program
    int 21h

    كه يك دستور خروج ساده است.
    و دومي و سومي:
    mov ax,4C01h ; end program with an errorlevel =1
    int 21h
    = = = = = =
    mov ax,4C02h ; end program with an errorlevel =2
    int 21h
    مي بينيد كه 4c00 نيست و اعداد يك و دو در آن هست. يعني دارد به سيستم خطا را هم اعلام مي كند. البته من نمي دونم سيستم الان هم براش مهم است اين خطا ها يا فقط قديم در زمان dos مهم بوده. كلا من بحثي فعلا برايش ندارم.

    حالا اين چند خروجي داشتن از اين لحاظ براي من جالب بود كه :
    در برنامه مي بينيد كه برنامه در دستور خروج اول كارش تمام شده و در دستور خروج پايان مي يابد. اين طوري كدهاي بعدي كه كارشان چاپ پيغام خطا است در دسترس نيست و نمي خواهد جامپ كنيم از رويش و خيلي كار راحت تره.

    اما برويم انتهاي برنامه راتوضيح بدهيم. يعني اينجا را:
    .data
    Handle DW ? ; to store file handle
    FileName DB "C:\test.txt",0 ; file to be opened
    OpenError DB "An error has occured(opening)!$"
    ReadError DB "An error has occured(reading)!$"
    Buffer DB 100 dup (?) ; buffer to store data

    قسمت داده است اين قسمت و قبلا هم باهاش آشنا بوديد.
    اولي هندل است. كه دو بايتي يعني يك كلمه است و مقدار اوليه بهش داده نشده و بعدا هندل درونش ريخته مي شود كه در قسمت فايل خواني در پايين شرح مي دهيم.
    دومي يك رشته است كه مي دانيد رشته هاي كاراكتري را از نوع بايت انتخاب مي كنند . و در اينجا هم از نوع بايت انتخاب شده. كه مسير فايل درونش ريخته شده.
    سومي و چهارمي هم كه پيغامهاي خطا است و بحثي ندارد.
    و آخري هم كه نام متغير را ((بافر)) گذاشته و باز از نوع بايت است و 100 بايت رزرو كرده. و باز مقدار اوليه نداده و علامت سئوال گذاشته.

    = = = = == == ==
    حالا برويم از اول فايل توضيح بدهيم:

    دو خط اول كه تنظيم قطعه داده است و به كرات استفاده شده و توضيح نياز ندارد. يعني اين قسمت:
    mov ax,@data ; base address of data segment
    mov ds,ax ; put this in ds
    قسمت بعدي يعني اين قسمت:
    mov dx,OFFSET FileName ; put address of filename in dx
    mov al,2 ; access mode - read and write
    mov ah,3Dh ; function 3Dh -open a file
    int 21h ; call DOS service

    قسمتي است كه فايل را باز مي كند. يعني open كننده است. كلمه open را براي اين آوردم چون كه اگر كسي با زبانهاي ديگر كار كرده باشه سريع مي فهمد كدام قسمت است. كلا فايل خواني در اكثر زبانها يكسان است.

    در زير ورودي و خروجي سرويس باز كننده فايل كه يكي از سرويس هاي وقفه 21 است را با هم مي بينيم:
    کد (Text):

    INPUT:

    AH = 3Dh
    AL = bits 0-2 Access mode
    000 = read only
    001 = write only
    010 = read/write
    bits 4-6 Sharing mode (DOS 3+)
    000 = compatibility mode
    001 = deny all
    010 = deny write
    011 = deny read
    100 = deny none
    DS:DX = segment:offset of ASCIIZ pathname

    OUTPUT:

    CF = 0 function is succesful
    AX = handle
    CF = 1 error has occured
    AX = error code
    01h missing file sharing software
    02h file not found
    03h path not found or file does not exist
    04h no handle available
    05h access denied
    0Ch access mode not permitted
     
    توضيح:
    اول شماره سرويس را در ah قرار مي دهيم كه 3d است.
    ميشه شماره سرويس را هم جزو ورودي ها دانست البته.
    بعد al را تنظيم مي كنيم. مي دانيد كه al داراي 8 بيت است.
    3 بيت اول براي نوع دسترسي است(بيت ها را از سمت راست مي خوانند) كه شماره هاي صفر و يك و دو براي ((فقط خواندن)) ((فقط نوشتن)) و ((خواندن و نوشتن)) است. در برنامه ما در al 2 گذاشته ايم يعني هم خواندن و هم نوشتن.

    بيتهاي شماره 4 تا 6 درون al براي Sharing mode است كه من فعلا نمي دانم چيه.
    مي دانيد كه بيت اول 1 است و بعدي 2 و بعدي 4 و بعدي 8 . پس بيتهاي صفر تا 7 را اينطوري برويد بالا. مثلا اگر بيت اول روشن باشه و آخري ميشه 1 بعلاوه 128 كه ميشه 129 . البته در مبناي 10 است اين عدد.
    براي مبناي 16 مي توانيد 4 بيت 4 بيت در نظر بگيريد.
    در مورد 129 . در بيتهاي 0 تا 3 داريم ((يك –صفر- صفر-صفر))
    و در بيتهاي 4 تا 7 داريم (( صفر-صفر – صفر – يك)) كه اين 4 بيت را باز اين طوري بخوانيد ((يك – دو – چهار – هشت)) پس ما 8 داريم در 4 بيت دوم و يك داريم در 4 بيت اول كه ميشه 81 در مبناي 16.

    از ورودي هاي ديگر مسير فايل است كه بايد روي متغيري كه حاوي آن است قبل اجراي سرويس تنظيم باشه. درست مثل چاپ رشته اي در قطعه داده كه اول روي آن متغير رشته اي تنظيم مي كرديم اين كار انجام شده. (مثل چاپ همين پيغام هاي خطا. ولي اينجا چاپي صورت نمي گيرد بلكه رشته توسط سرويس دريافت مي شود.كه مسير فايل است.)
     
    آخرین ویرایش: ‏29 سپتامبر 2019
    نوشته شده توسط saalek110 در ‏8 آوریل 2008
  4. saalek110

    saalek110 Well-Known Member

    ارسال‌ها:
    2,765
    تشکر شده:
    1,382
    امتیاز دستاورد:
    113
    ادامه پست قبل:

    حالا خروجي ها:
    دو حالت دارد. يكي اينكه كار موفقيت آميز بوده . يعني فايل باز شده كه هندل در ax قرار مي گيرد. حالا مي گيم هندل چيه.
    در حالت موفقيت آميز فلاگ cf صفر است.

    حالت بعدي شكست در باز كردن فايل است كه فلاگ cf يك مي شود و كد خطا در ax قرار مي گيرد.
    حالا اينكه هر كد چه معني ئي دارد اينهاست:
    01h missing file sharing software
    02h file not found
    03h path not found or file does not exist
    04h no handle available
    05h access denied
    0Ch access mode not permitted
    كه خودتان ترجمه كنيد. اطلاعات من در اين مورد بيشتر از شما نيست.

    اما در اينجا كه بالا گفته:
    DS:DX = segment:eek:ffset of ASCIIZ pathname
    يعني چه؟
    اين ASCIIZ را مي گويم يعني چه؟
    جواب: در كدهاي نمونه برنامه ، در قسمت تعريف متغيرها در قسمت داده ها ، 3 متغير رشته اي تعريف شده. يعني اينها:
    FileName DB "C:\test.txt",0 ; file to be opened
    OpenError DB "An error has occured(opening)!$"
    ReadError DB "An error has occured(reading)!$"

    مي بينيد كه دو تاي آخري كه براي چاپ يك پيغام است با علامت دلار پايان يافته. و قبلا هم من گفتم كه مواظب باشيد در پايان رشته هاي براي چاپ اين علامت دلار را يادتان نرود چون ((نشانه پايان رشته)) است و اگر نباشه همين طوري رشته به خواندن ادامه داده ميشه تا بطور اتفاقي يك دلار پيدا بشه و بياستد.
    ولي 3 خط كد بالا ، اولي كه مسير فايل است با دلار خاتمه نيافته بلكه با ((صفر )) خاتمه پيدا كرده. به اين ASCIIZ مي گويند. كه يك صفر تهش داره. صفر كه مي دونيد ميشه zero .
    و اون يكي اسكي (ASCII ) بدون z بود و با دلار خاتمه مي يابد.

    حالا برسيم به هندل:
    هندل خروجي سرويسه كه در ax ريخته مي شود و در خط زير:
    mov Handle,ax ; save file handle for later

    درون متغير ريخته ميشود. متغير هم word گرفته شده تا اندازه ax باشه.
    در سايت گفته براي نگهداري آن ميشه از رجيستر هم استفاده بشه ولي اين جوري يكي همش بايد يادمان باشه كه هندل توي اونه و ديگري اين كه اون رجيستر اشغال مي مونه و نميشه ازش براي كارهاي ديگه استفاده كرد.

    حالا هندل چيه؟
    ببينيد وقتي تابع open كه در اين برنامه اسمبلي يك سرويس از يك وقفه است تابعي را باز مي كند ، چيزي مثل يك پرچم ايجاد مي كنه يا مثل يك ويزاي عبور كه تمام توابعي كه بخواهند از اون فايل استفاده كنند بايد اين ويزا را نشان دهند. خيلي هم خوبه اين ويزا داشتن . چون مثل رشته اي توابع را بهم مرتبط مي كند.

    خط بعدي:
    jc ErrorOpening ; jump if carry flag set - error!
    اين هم يك پرش شرطي كه احتمالا به فلاگ cf نگاه مي كند. چون در اين برنامه و آموزش كه حرفي از فلاگ ديگري نبوده.

    خوب نتيجه open فايل چي شد؟ شد يك هندل كه ريختيم در يك متغير و داريمش.
    حالا برويم بقيه كدها را بخوانيم.

    اين كد:
    mov dx,offset Buffer ; address of buffer in dx
    mov bx,Handle ; handle in bx
    mov cx,100 ; amount of bytes to be read
    mov ah,3Fh ; function 3Fh - read from file
    int 21h ; call dos service

    اول راهنماي ورودي و خروجي اين سرويس:
    کد (Text):

    INPUT:

    AH = 3Fh
    BX = handle
    CX = number of bytes to be read
    DS:DX = segment:offset of a buffer

    OUTPUT:

    CF = 0 function is successful
    AX = number of bytes read
    CF = 1 an error has occurred
    05h access denied
    06h illegal handle or file not opened
     
    اول شماره سرويس كه 3f است.
    بعد هندل است كه بايد در bx وجود داشته باشد.
    در cx هم تعداد بايتهايي كه بايد خوانده شود. ديگه شمارشگر بودن cx را خوب حس كرديم.

    قضيه بعدي در كد برنامه ما اين:
    mov dx,offset Buffer ; address of buffer in dx
    است.
    يعني كه ما آدرس بافر را مي دهيم تا هر چي از فايل خوانده شود برود داخلش.
    از فايل به بافر. از هارد به ram (در قطعه داده).

    حالا خروجي سرويس:
    اول فلاگ cf است كه باز اگر صفر بود يعني كار خوانده موفقيت آميز بوده و در اين حالا تعداد بايتهاي خوانده شده در ax منعكس مي شود ،
    و اگر عمل با شكست مواجه شود ، cf آنگاه (( يك)) خواهد شد.
    و اينها:
    05h access denied
    06h illegal handle or file not opened
    احتمالا ميرود داخل ax . من اينجا را نفهميدم.
    در ادامه توضيحات سايت گفته كه اگر cf صفر شد و ax هم صفر بود ، يعني كه به اشاره گر به انتهاي فايل رسيده و بيشتر از اين نميشه خواند.
    منظور از اشاره گر اينه كه وقتي از داخل فايل چيزي خوانده ميشه ، ميره خط بعد تا خط بعدي خوانده شود.
    و اگر cf صفر بود و ax كوچكتر از cx بود ، يعني كه قسمتي از فايل خوانده شده و كار متوقف شده كه يا به علت رسيدن به انتهاي فايل بوده يا به علت رخ دادن خطايي.
    اين چند خط توضيح را با اين :
    05h access denied
    06h illegal handle or file not opened
    فكر كنم بشه يك جورايي با هم جمع كرد. خودتان تحقيق كنيد. من هم اگر جايي بود كه بهتر توضيح داده بود مي گويم.

    برويم قسمت بعدي برنامه امان:
    mov bx,Handle ; put file handle in bx
    mov ah,3Eh ; function 3Eh - close a file
    int 21h ; call DOS service

    اين هم سرويس ديگري است كه 3e است و باز هندل مي خواهد . كارش هم بستن فايل است.
    اين هم ورودي و خروجي اين سرويس:
    کد (Text):

    INPUT:

    AX = 3Eh
    BX = file handle


    OUTPUT:

    CF = 0 function is successful
    AX = destroyed
    CF = 1 function not successful
    AX = error code - 06h file not opened or unauthorised handle.
     
    باز در خروجي به cf و ax ريخته ميشه كه اگر cf صفر باشه يعني موفقيت آميز و اگر cf يك باشد يعني شكست و كد خطا مي رود در ax .
    نكته خطري اين close كردن:
    اگر بدون هندل(يعني وقتي هندل صفر باشد) close كنيد ، ديگه شما فايل را close نكرده ايد و اينپوت استاندارد يعني كيبورد را close كرده ايد و ديگر هيچ چيزي نمي توانيد وارد كنيد.

    خوب. خسته نباشيد.

    ===================================
    انگار تكه آخر برنامه را توضيح نداديم. اين قسمت را:

    mov cx,100 ; length of string
    mov si,OFFSET Buffer ; DS:SI - address of string
    xor bh,bh ; video page 11- 0
    mov ah,0Eh ; function 0Eh - write character

    NextChar:

    lodsb ; AL = next character in string
    int 10h ; call BIOS service
    loop NextChar

    به شرح سرويس 0E از وقفه 10 كه از آموزشهاي اموليتور نقل مي كنم توجه كنيد:
    کد (Text):

    INT 10h / AH = 0Eh - teletype output.


    input:
    AL = character to write.
    This functions displays a character on the screen,
    advancing the cursor and scrolling the screen as necessary.
    The printing is always done to current active page.
     
    اين سرويس خروجي تله تايپ مي دهد.
    اين سرويس چاپ مي كند و بعد كرزر را جلو مي برد و در صورت نياز صفحه را اسكرول مي كند . و در صفحه جاري مي نويسد.

    و اينجا:
    xor bh,bh ; video page – 0
    آمده ايم با xor كردن ، bh را صفر كرده ايم. (تنظيم صفحه جاري.)
    در :
    mov cx,100 ; length of string
    آمده ايم cx را تنظيم كرده ايم تا در لوپ استفاده شود.
    اين خط هم:
    mov si,OFFSET Buffer ; DS:SI - address of string
    احتمالا براي استفاده lodsb است. اين كه مي گويم احتمالا چون من تا نروم با lodsb يك برنامه نسازم مطمئن نمي شوم. ولي همينه به احتمال زياد.
    خلاصه تكه برنامه :

    mov cx,100 ; length of string
    mov si,OFFSET Buffer ; DS:SI - address of string
    xor bh,bh ; video page - 0
    mov ah,0Eh ; function 0Eh - write character

    NextChar:

    lodsb ; AL = next character in string
    int 10h ; call BIOS service
    loop NextChar

    اين ميشه كه از قطعه داده در al بار ميشه با lodsb و بعد سرويس 0E از وقفه 10 مي آيد محتواي al را چاپ مي كند. و حلقه هم كارش اين است كه كار بار شدن و چاپ را 100 بار تكرار كند.
     
    آخرین ویرایش: ‏29 سپتامبر 2019
    نوشته شده توسط saalek110 در ‏8 آوریل 2008
  5. saalek110

    saalek110 Well-Known Member

    ارسال‌ها:
    2,765
    تشکر شده:
    1,382
    امتیاز دستاورد:
    113
    از صفحه 5 باز مانده كه ايجاد فايل – جستجوي فايل و غيره است كه فعلا حسش نيست بگم.
    == = = = = = ==
    اما راجع به پرشهاي شرطي عكس زير كه مقايسه بعضي پرشهاي شرطي با همتاي زبان سي است را مي گذارم كه فكر كنم جالب باشه.

    a1.jpg

    اين هم يك مثال از jnz :
    کد (Text):

    MOV CX, 20            ;We will execute COUNT_LOOP 20 times
    COUNT_LOOP:          ;Main entry point for loop
        DEC CX            ;Subtract 1 from CX
        JNZ COUNT_LOOP    ;If CX is zero, continue on to
                          ;next code, otherwise JMP back to COUNT_LOOP
     
    يعني وقتي cx صفر بشه ديگه پرش انجام نميشه.
    = = = = = == ==
    اين هم يك مثال از jz :
    کد (Text):

    MOV AX, 0010B ;move the decimal value '2' into the AX register
    MOV CX, 0001B ;mov the decimal value '1' into the CX register
    CMP AX, CX    ;Compare AX and CX by subtracting the contents of CX from AX
      JZ Was_zero  ;Jumpt to Was_zero label if result from CMP was ZERO
    ....      
    ....          ;Code to implement if Values were not equal
     
    در كد بالا ،وقتي نتيجه تفريق(تفريق انجام نميشه با cmp ، فقط فلاگها تنظيم مي شوند. تفريق واقعي همان sub است. ) صفر باشد پرش مي كند.
     
    آخرین ویرایش: ‏29 سپتامبر 2019
    نوشته شده توسط saalek110 در ‏8 آوریل 2008
  6. saalek110

    saalek110 Well-Known Member

    ارسال‌ها:
    2,765
    تشکر شده:
    1,382
    امتیاز دستاورد:
    113
    ليست وقفه ها :
    در اين سايت :
    http://www.cs.cmu.edu/afs/cs/user/ralf/pub/WWW/files.html

    همان بالاي صفحه يك سري فايل براي دانلود هست كه من اولي را دانلود كردم.

    اما با ديدن محتواي اين فايل كه پسوند هاي غيرمعمولي داشتند و با word و اديتور كدوايز توانستم باز كنم ، بايد بگم كه،

    نه توصيه به دانلود مي كنم نه پرهيز از دانلود.

    اگر مجموعه اي مي خواهيد و مي خواهيد كارهاي تحقيقي كنيد(عشق به اسمبلي – اعصاب و ...) ......
    ولي اگر وقت نداريد و حوصله كم داريد.....
     
    نوشته شده توسط saalek110 در ‏8 آوریل 2008
  7. saalek110

    saalek110 Well-Known Member

    ارسال‌ها:
    2,765
    تشکر شده:
    1,382
    امتیاز دستاورد:
    113
    اگر مي خواهيد برنامه اي داشته باشيد كه كليدي را از كيبورد بگيرد و ضمن نمايش آن حرف بر صفحه كد آن را هم در al بريزد، از برنامه زير استفاده كنيد.
    کد (Text):

    .model small
    .stack
    .data
    .code
    asli proc
    ;------------------
    mov ah, 1
    int 21h
    ;------------------
    mov ax,4c00h ; return to dos DOS
    int 21h

    asli endp
         end asli

     
    برنامه بالا را من امتحان كردم. قبل اجراي وقفه و بعد آن آمدم al را چاپ كردم كه الو صفر بود بعد شد كد كاراكتر زده شده.
    وقتي كليدي را بزنيم و آن كليد چاپ شود بر صفحه ، مي گوييم داراي اكو است.

    اگر همين كار يعني گرفتن و ذخيره در al را بدون اكو مي خواهيد از سرويس 7 به جاي سروي 1 استفاده كنيد.
    mov ah, 7


    راهنماي آن:
    کد (Text):

    INT 21h / AH=1 - read character from standard input,
    with echo, result is stored in AL.
    if there is no character in the keyboard buffer,
    the function waits until any key is pressed.

    example:


    mov ah, 1
    int 21h
     
    قبلا من يك برنامه حلقه تو در تو ساختم تا وقفه زماني ايجاد كنم ولي وقفه اي هست كه تاخير ايجاد مي كند و راهنماي آن را در زير مي آورم. البته شايد وقفه هاي ديگري نيز براي اين كار باشد.
    نكته : اين وقفه در ويندوز xp عمل نمي كند.
    کد (Text):

    INT 15h / AH = 86h - BIOS wait function.
    input:

    CX:DX = interval in microseconds
    return:

    CF clear if successful (wait interval elapsed),
    CF set on error or when wait function is already in progress.

    Note:
    the resolution of the wait period is 977 microseconds
    on many systems (1 million microseconds - 1 second).
    Windows XP does not support this interrupt (always sets CF=1).

     
    اگر cf به يك تغيير كند به معني شكست كه در ويندوز ايكس پي بايد چنين شود.
    همين طور كه در زير مي بينيد:
    INT 15h / AH = 86h - BIOS wait function.
    input:

    CX:DX = interval in microseconds
    شماره سرويس آمده و اين كه زمان دلخواه را بايد در چه رجيسترهايي بريزيم.
     
    آخرین ویرایش: ‏29 سپتامبر 2019
    نوشته شده توسط saalek110 در ‏8 آوریل 2008
  8. saalek110

    saalek110 Well-Known Member

    ارسال‌ها:
    2,765
    تشکر شده:
    1,382
    امتیاز دستاورد:
    113
    كار با ماوس:
    وقفه 33 براي اين كار به كار مي رود.
    براي استفاده از ماوس اول بايد راهش انداخت:
    mov ax, 0 ; initilize mouse
    int 33h

    mov ax, 1 ; show mouse
    int 33h
    در دو سرويس بالا ، اولي اينيتيالايز و دومي show ماوس است. من امتحان كردم . يكي هم كه كم باشه ماوس نشان داده نمي شود.
    به برنامه زير دقت كنيد:
    کد (Text):

    .model small
    .stack
    .data
    .code
    asli proc
    ;------------------
    mov ax, 0 ; initilize mouse
    int 33h

    mov ax, 1 ; show mouse
    int 33h
    ;-------- wait ----------------
    MOV AH,00H
    INT 16H
    ;-------------------------------
    mov ax, 2  ;makhfi kardane(hide) moushe
    int 33h
    ;------------------
    ;-------- wait ----------------
    MOV AH,00H
    INT 16H
    ;-------------------------------
    mov ax,4c00h ; return to dos DOS
    int 21h

    asli endp
         end asli



     
    در اين برنامه ابتدا ماوس اينيتيالايز و show شده.
    بعد من با دو خط كد حالت انتظار در برنامه بوجود آورده ام براي گرفتن كليدي.
    و با زدن كليد مي رود به دو خط بعدي. يعني:
    mov ax,4c00h ; return to dos DOS
    int 21h
    اين دو خط ماوس را hide ، يعني مخفي مي كند. اگر اين دو خط نباشد بعد اختتام برنامه هم باز ماوس وجود خواهد داشت.
    من يك wait هم بعد خاموشي ماوس گذاشته ام در كد بالا ، تا خاموشي ماوس را ببينيد.

    نكته: در حالت full screen بايد ماوس را ببينيد. با همين نام دكمه اي روي تولبار پرومپت داس خود داريد كه آن را بزنيد.

    = == = = = = == = = =
    نكات ماوس:
    اول راهنماي اينيتيالايز:
    کد (Text):

    INT 33h / AX=0000 - mouse ininialization. any previous mouse pointer is hidden.

    returns:
    if successful: AX=0FFFFh and BX=number of mouse buttons.
    if failed: AX=0
     
    با موفقيت آميز بودن ax مساوي 0ffff و bx مساوي تعداد دكمه هاي ماوس مي شود. و در صورت شكست ax صفر مي شود. من امتحان كردم به من ffff داد ax را و عدد 2 براي bx . ماوس من دو دكمه چپ كليك و راست كليك دارد. شايد براي اين است. وسط كليك ندارد.
    = = =
    سرويس show و hide راهنما ندارد.

    در برنامه بالا ، سرويس هاي صفر و يك و دو استفاده شده بود براي اينيتيالايز و show و hide .
    سرويس ديگري داريم با شماره 3 .
    راهنما:
    کد (Text):

    INT 33h / AX=0003 - get mouse position and status of its buttons.

    returns:
    if left button is down: BX=1
    if right button is down: BX=2
    if both buttons are down: BX=3
    CX = x
    DX = y
    example:

    mov ax, 3
    int 33h

    ; note: in graphical 320x200 mode the value of CX is doubled.
     
    مي دانيد كه برنامه قبلي ما كار خاصي انجام نمي داد. چون فقط روشن و خاموش مي كرد ماوس را. اصل قضيه همين سرويس 3 است. حالا چه برنامه اي بنويسيم تا اين را بكار ببريم؟!
    يك حلقه خوبه نه؟ كه مدام مختصات ماوس را نشان دهد.
    در راهنماي بالا مي بينيد كه مختصات ماوس در cx و dx ريخته مي شود. پس من در زير برنامه اي مي گذارم كه در حلقه اي مدام cx و dx را چاپ كند:
    کد (Text):

    .model small
    .stack
    .data
    .code
    asli proc
    ;------------------
    mov ax, 0 ; initilize mouse
    int 33h

    mov ax, 1 ; show mouse
    int 33h
    ;========= halgheh =================
    lable_first:
    ;---------service 3
    mov ax, 3
    int 33h
    ;---------curser be avale safeh
    push dx
    mov dh,0  ;DH = row.
    mov dl,0  ;DL = column.
    mov bh,0
    mov ah,2  ;service
    int 10h
    pop dx
    ;------------------------------

    mov bl,ch
    call bl_print
    mov bl,cl
    call bl_print

    mov bl,dh
    call bl_print
    mov bl,dl
    call bl_print

    jmp lable_first
    ;=================================
    mov ax, 2  ;makhfi kardane(hide) moushe
    int 33h
    ;------------------
    mov ax,4c00h ; return to dos DOS
    int 21h

    asli endp
    ; ============ sub bl_print ===========
    bl_print PROC NEAR
    push ax
    push bx
    push cx
    push dx
    ;----------part 1
    mov ah,2h
    mov dl,bl

    mov cl,04h
    shr dl,cl

    add dl,30h

    cmp dl,3ah
    jl lable1

    add dl,07h

    lable1:
    int 21h

    ; -----------part 2

    mov dl,bl
    and dl,0fh

    add dl,30h

    cmp dl,3ah
    jl lable2

    add dl,07h

    lable2:
    int 21h
    ;------------
    pop dx
    pop cx
    pop bx
    pop ax

    ret ; return to where it was called
    bl_print ENDP
    ;================================

         end asli

     
    شرح برنامه:
    يك حلقه با دستور jmp يعني جامپ ساخته شده كه با خطهايي كه با مساوي كشيده ام ، محدوده حلقه مشخص شده. قبل حلقه هم كه ماوس قبلا روشن شده بود.
    اما ، داخل حلقه ، اول ليبل است كه جامپ به آنجا انجام مي شود. بعد سرويس 3 از وقفه 33 را داريم. و بعد هم 7 خطي كه كرزر را به اول صفحه مي برد. مي توانيد اين 7 خط را حذف كنيد ولي با اين كار اعداد همين طور به پايين مي روند و منظره خوبي ندارد.
    بعد اين 7 خط هم من با صدا كردن bl_print آمده ام cx و dx را چاپ كرده ام.

    كار قشنگ تر اينه كه cx و dx را چاپ نكنيم. بلكه در مكان موس كاري چاپي انجام بشود كه خودتان برنامه اش را بسازيد.
    آخرين خط داخل حلقه هم همان دستور جامپ است.
    == = == = =
    بايد برنامه اي هم بنويسيد براي دريافت bx براي تست اين قسمت:
    if left button is down: BX=1
    if right button is down: BX=2
    if both buttons are down: BX=3
    براي اين كار به جاي اين قسمت در برنامه بالا:
    ;---------curser be avale safeh
    push dx
    mov dh,0 ;DH = row.
    mov dl,0 ;DL = column.
    mov bh,0
    mov ah,2 ;service
    int 10h
    pop dx
    ;------------------------------

    mov bl,ch
    call bl_print
    mov bl,cl
    call bl_print

    mov bl,dh
    call bl_print
    mov bl,dl
    call bl_print
    اين قسمت را جايگزين كنيد:
    ;---------curser be avale safeh
    push bx
    mov dh,0 ;DH = row.
    mov dl,0 ;DL = column.
    mov bh,0
    mov ah,2 ;service
    int 10h
    pop bx
    ;------------------------------

    push bx
    mov bl,bh
    call bl_print
    pop bx
    call bl_print

    با اين جايگزيني ، باعث چاپ bx مي شويد و با كليك چپ عدد ((يك)) و با كليك راست عدد ((دو)) چاپ مي شود.

    اما در قسمت جايگزين شده دقت كنيد كه اطراف آن 7 خط انتقال كرزر قبل جايگزيني من dx را push كردم و بعد جايگزيني bx را push كردم . چون در برنامه اول ما مي خواستيم dx را چاپ كنيم ولي در برنامه دوم مي خواستيم bx را چاپ كنيم.

    در قسمت جايگزين شده به اين خط ها نگاه كنيد:
    push bx
    mov bl,bh
    call bl_print
    pop bx
    call bl_print
    در خط :
    mov bl,bh
    مي بينيد كه bl دارد نابود مي شود ، در صورتي كه بايد در خطهاي بعدي چاپ شود. پس قبل نابودي اش من آنرا push كرده ام تا مصون بماند. و بعد pop مستقيما آمده ام bl_print را احضار كرده ام چون ديگه نياز نيست كه bl را روي bl بريزم.

    نكته: در مود كاراكتري موس به شكل مستطيل است و در مود گرافيكي به شكل رايج موس يعني فلش مانند.
    همچنين در اين پست در راهنماها به تغيير اندازه اي در مود گرافيكي اشاره شده كه به آن توجه كنيد.

    ; note: in graphical 320x200 mode the value of CX is doubled.
     
    آخرین ویرایش: ‏29 سپتامبر 2019
    نوشته شده توسط saalek110 در ‏8 آوریل 2008
  9. saalek110

    saalek110 Well-Known Member

    ارسال‌ها:
    2,765
    تشکر شده:
    1,382
    امتیاز دستاورد:
    113
    این برنامه نوعی تمرین بر مباحث قبلی است. کار این برنامه چاپ یک رجیستر در مبنای 2 است.
    کد (Text):

    .model small
    .stack
    .data
    .code
    asli proc
    ;------------------------------------
    mov bl,6

    mov ah,2
    mov cx,8
    my_lable:
    mov dl,0
    rcl bl,1
    adc dl,30h
    int 21h
    loop my_lable
    ; -------- key --------------
    xor ax,ax ; function 00h - get a key
    int 16h ; call BIOS service
    ; ---------------------------
    ;-------------------------------------
    mov ax,4c00h ; return to dos DOS
    int 21h

    asli endp
         end asli
     
    برنامه را بین دو خط افقی محصور کردم تا با قالب برنامه که شما می توانید قالب دلخواه خود را جایگزین کنید مخلوط نشود.
    یک تکه هم که باز با خط افقی محصور شده و با کلمه key عنوان داده شده همان طور که در برنامه های قبلی هم بکار بردیم برای این است که بعد چاپ نتایج برنامه از حالت اجرا خارج نشود تا ما بتوانیم نتیجه اجرا را ببینیم. تا کلیدی زده نشود برنامه به پایان نمی رسد.

    شرح برنامه:
    در خط اول یعنی
    mov bl,6
    به bl مقدار اولیه داده ایم. عدد 6 یعنی که بیت دوم و سوم عدد از سمت راست باید 1 باشد و بقیه صفر باشد. برای سادگی این عدد را انتخاب کرده ام. البته با اعداد دیگر هم امتحان کرده ام من ولی با اجرای برنامه بالا باید به:
    00000110
    برسید.
    یعنی همان 6 در مبنای 2 . اگر می خواهید همه یک شوند باید به bl مقدار0ffh بدهید. می دانید که اگر عددی با حرف شروع شود یک صفر قبل آن باید گذاشت.

    خط دوم یعنی
    mov ah,2
    که می دانید آمادگی چاپ است برای وقفه
    int 21h

    بقیه برنامه را کلی توضیح می دهم چون همه به هم مربوط است.
    ما می آییم bl را با دستور rcl چرخش می دهیم. دستور چرخش با دستور شیفت که قبلا در این تاپیک استفاده کردیم فرق دارد. در چرخش عدد از آن طرف دوباره به خود برمیگردد. شما اینجا بیتهای bl که 8 تا است (و به همین دلیل cx که تعداد چرخش حلقه است 8 تنظیم شده) و بیت فلاگ نقل را با هم در نظر بگیرید.
    یک چرخش بین این 9 بیت در جریان است. یعنی هر بیت اول به فلاگ نقل می رود و بعد از آن طرف دوباره وارد bl می شود. و وقتی محتوای بیت داخل فلاگ نقلی است فرصت خوبی است تا آن را چاپ کنیم. فکر کنم دستورات دیگر هم باشد که چرخش بدهد ولی داخل فلاگ نقلی نیاندازد ولی برای ما در اینجا رفتن به فلاگ نقل یک فرصت است.
    دستور adc قبلا هم شرح داده شده در این تاپیک. ولی باز می گویم . کارش این است که دو عدد را جمع می کند و همزمان با جمع دو عدد می آید فلاگ نقل را هم جمع می زند. ما آمده ایم با 30h جمع زده ایم تا موقع چاپ ((صفر یا یک )) چاپ شود. قبلا در برنامه bl_print شرح دادیم که فلسفه این عدد 30h چیست.
    فکر کنم توضیح کافی باشد. با تغییر دادن برنامه می توانید بیشتر بفهمید که کار هر دستور چیست.
     
    نوشته شده توسط saalek110 در ‏8 آوریل 2008
  10. saalek110

    saalek110 Well-Known Member

    ارسال‌ها:
    2,765
    تشکر شده:
    1,382
    امتیاز دستاورد:
    113
    مطلب زیر هم برای یک مرور فکر کنم دید بدهد:
    از تاپیک: آموزش crack...فقط علاقه مندان لطفاً
    http://forum.persiantools.com/showthread.php?t=2701

     
    نوشته شده توسط saalek110 در ‏8 آوریل 2008
    hamed.rafiee از این پست تشکر کرده است.
  11. saalek110

    saalek110 Well-Known Member

    ارسال‌ها:
    2,765
    تشکر شده:
    1,382
    امتیاز دستاورد:
    113
    نوشته شده توسط saalek110 در ‏30 دسامبر 2008
  12. saalek110

    saalek110 Well-Known Member

    ارسال‌ها:
    2,765
    تشکر شده:
    1,382
    امتیاز دستاورد:
    113
    http://www.relaxiha.com/forums//showthread.php?t=19996&p=47262
    آموزش برنامه نویسی اسمبلی در ویندوز ایکس پی
    نوشته: آقای وحید نصیری.
    pdf
    61 صفحه.
    500 کیلو.
    برای دانلود باید در فروم عضو شوید و چند پست هم بزنید. سرچ کنید شاید در سایتهای دیگر هم موجود باشد.
     
    نوشته شده توسط saalek110 در ‏11 ژانویه 2009
  13. saalek110

    saalek110 Well-Known Member

    ارسال‌ها:
    2,765
    تشکر شده:
    1,382
    امتیاز دستاورد:
    113
    مهر 1398:
    up
    از مدیر تالار درخواست کردم قفل تاپیک را بردارد تا پستهای خودم را در این تاپیک اصلاح کنم.
    در صفحه 2 یعنی شروع پستهای خودم فایلهای ضروری را ضمیمه کردم. و یک عکس را جایگزین کردم.
    من فایلهای asm یعنی سورس اسمبلی را با Tasm تبدیل می کردم. ولی الان ویندوز من 64 بیت است و Tasm کار نمی کند. ممکن است ویندوز شما 32 بیت باشد و Tasm برای شما کار کند.
    به نظرم بهتر است پستهای این تاپیک بهم نخورد. این تاپیک برای ویندوز 32 بیت مناسب است.
    یک سری عکس بود بخاطر ازبین رفتن هاست مجانی عکس آدمک نشان می داد که عکسها را با عکسی حاوی نوشته no image جایگزین کردم. a1.jpg چون ویندوز من الان 64 بیت است و نمی توانم با کدها کار کنم پس قادر به تهیه مجدد عکسها نبودم.
     
    آخرین ویرایش: ‏29 سپتامبر 2019
    نوشته شده توسط saalek110 در ‏28 سپتامبر 2019
وضعیت موضوع:
موضوع بسته شده است.

به اشتراک بگذارید