I'm trying to display the carriage return and line feed in my code but it does not work. If I print out the codes as a string it works. Help needed. Thanks in advance.
; A 16-bit DOS program that receives a single char from STDIN and then prints it out to ;STDOUT
.MODEL small
.stack 100h
.data
char_prompt db 'Please input a character: ','$'
out_msg1 db 'Character entered is: ','$'
out_msg2 db 0dh,0ah, '$'
.code
start:
mov ax, #data
mov ds, ax ; Set DS segment
mov dx, offset char_prompt; display msg1
mov ah,9
int 21h
mov ah, 01h ;store char in BL
int 21h
mov bl, al
mov dl, 0dh; ;output CR
mov ah, 02h
int 21
mov dl, 0ah ;output LF
mov ah, 02h
int 21
mov dx, offset out_msg1 ;display msg2
mov ah,9
int 21h
mov dl, bl ;display char
mov ah, 02h
int 21h
mov ax, 4C00h
int 21h
end start
Your code is wrong:
Look carefully at the int parts:
mov dl, 0dh; ;output CR
mov ah, 02h
int 21
mov dl, 0ah ;output LF
mov ah, 02h
int 21
What are you missing? INT 21 is NOT correct!! It should be INT 21H
try this:
mov ah, 06h
mov dl, 0dh ; CR
int 21h
mov ah, 06h
mov dl, 0ah ; LF
int 21h
Have to say this, this is a blast from the past... :)
Had to go to my favorite site Ralf Brown's Interrupt list... to remember what was the instruction for the direct console output..
Edit: as per Gunner pointed out.. yeah the 'h' is missing.. am too bloody old... :P He deserved the upvotes etc :)
Related
Task: write a program to remove the central character in all words of odd length in a given text.
I did this (the idea of the algorithm is to find and write the indexes by which the space is located (in the first cycle) and then rewrite the string with missing characters where necessary):
.586
.model flat, C
option casemap: none
include c:\masm32\include\msvcrt.inc
include c:\masm32\include\kernel32.inc
includelib c:\masm32\lib\msvcrt.lib
includelib c:\masm32\lib\kernel32.lib
printf PROTO C, :VARARG
.data
src db 'hello masm32_ wrld lb 7',0
len equ $-src
dest db ' ',len dup(0),0
end_index db len/2 dup(0)
msg2 db ' %d ', 0
count_1 db 0
count_2 db 0
.code
start:
symbol equ ' '
xor ecx,ecx
xor ebx,ebx
lea esi,src
dec ebx
next:
inc ebx
cmp byte ptr [esi],symbol
jnz notfound
inc ecx
mov byte ptr [end_index + ecx], bl
notfound:
inc esi
cmp byte ptr [esi],0
jz exit
jmp next
exit:
lea esi, src
lea edi, dest
mov ebx, 1
xor ecx, ecx
##_next:
.if byte ptr [end_index + ebx] == 0
jmp ##_ret
.endif
mov al, byte ptr [end_index + ebx]
mov ah, byte ptr [end_index + ebx - 1]
sub al, ah
xor ah, ah
push ebx
mov bl, 2
div bl
pop ebx
add al, byte ptr [end_index + ebx - 1]
and eax, 000000ffh
.if al == cl
inc count_1
inc count_2
inc ebx
jmp ##_next
.endif
mov al, byte ptr [esi + count_1]
mov byte ptr [edi + count_2], al
inc count_1
inc count_2
jmp ##_next
##_ret:
invoke printf, offset dest , 0
ret
end start
But at the first pass of the loop I get
An exception was thrown at address 0x00042092 in asm_7_deb.exe: 0xC0000005: Read access violation at address 0x0008A045.
dissassembler:
start:
00042020 xor ecx,ecx
00042022 xor ebx,ebx
00042024 lea esi,[src (045000h)]
0004202A dec ebx
next:
0004202B inc ebx
0004202C cmp byte ptr [esi],20h
0004202F jne _start+18h (042038h)
00042031 inc ecx
00042032 mov byte ptr end_index (045032h)[ecx],bl
notfound:
00042038 inc esi
00042039 cmp byte ptr [esi],0
0004203C je _start+20h (042040h)
0004203E jmp _start+0Bh (04202Bh)
exit:
00042040 lea esi,[src (045000h)]
00042046 lea edi,[dest (045018h)]
0004204C mov ebx,1
00042051 xor ecx,ecx
##_next:
00042053 cmp byte ptr end_index (045032h)[ebx],0
0004205A jne _start+3Eh (04205Eh)
0004205C jmp _start+8Ch (0420ACh)
#C0001:
0004205E mov al,byte ptr end_index (045032h)[ebx]
00042064 mov ah,byte ptr [ebx+45031h]
0004206A sub al,ah
0004206C xor ah,ah
0004206E push ebx
0004206F mov bl,2
00042071 div al,bl
00042073 pop ebx
00042074 add al,byte ptr [ebx+45031h]
0004207A and eax,0FFh
0004207F cmp al,cl
00042081 jne _start+72h (042092h)
00042083 inc byte ptr [count_1 (045045h)]
00042089 inc byte ptr [count_2 (045046h)]
0004208F inc ebx
00042090 jmp _start+33h (042053h)
#C0003:
00042092 mov al,byte ptr count_1 (045045h)[esi] ; <==== probably it happend here
00042098 mov byte ptr count_2 (045046h)[edi],al ; but i do not understand why
0004209E inc byte ptr [count_1 (045045h)]
000420A4 inc byte ptr [count_2 (045046h)]
000420AA jmp _start+33h (042053h)
##_ret:
000420AC push 0
000420AE push offset dest (045018h)
000420B3 call _printf (041005h)
000420B8 add esp,8
000420BB ret
In order to load [esi + count_1] you need to load the value of count_1 into a register first. Otherwise it takes the address of count_1 plus the value of esi, which is not what you want.
Since count_1 is a byte, use:
movzx edx, byte ptr [count_1]
mov al, [esi+edx]
I'm getting this error when running program:
Access violation writing location 0x0105100b
Does anyone know what's wrong with this code? It's breaking at mov [ecx],dl
.686
.model flat
extern _ExitProcess#4: PROC
public _main
.data
.code
data1 db 61H,62H,63H,64H,65H,66H,67H,68H,69H,70H,0H
data2 db 25 dup (?)
_main:
mov eax, OFFSET data1
mov ecx, OFFSET data2
mov edx, 0
mov ebp, ecx
sub ebp, eax ; licznik
mov dl, BYTE PTR [eax]
mov [ecx],dl
koniec:
push 0
call _ExitProcess#4
END
an application frequently dumped cores due to segmentation fault, and its backtrace looks like below.
(gdb) bt
#0 0x00000039c6c71874 in strncpy () from /lib64/libc.so.6
#1 0x00000000016fab83 in CcString::CcString (this=0x470008e0, str=...) at ../../base/src/ccString.cpp:163
#2 0x00000000016face9 in CcString::operator= (this=0x47000bf0, str=...) at ../../base/src/ccString.cpp:250
#3 0x0000000000441193 in RmsDbMgr::getFormatedNumber(const CallPartyNumber_t *, ._2039, CcString &) (this=0x2af86a4de008, apNumber=0xb90160, aFormatType=NUMBER_FORMAT_TYPE_LDAP, aFormatedNumber=...) at ../main/RmsDbMgr.cpp:4465
#4 0x0000000000b1cacf in SessionMt::sendLdapQueryReq (this=0x2cb8d580, apNumber=0x2cb90160, aRecipient=true) at ../session/SessionMt.cpp:1600
in frame 4, apNumber=0x2cb90160, but in frame 3 its value was changed to 0xb90160 and that pointer caused segmentation fault later.
what could cause that happen? and why backtrace format of frame 3 doesn't look quite similar to other lines?
i tried a little bit with assembly ...
(gdb) disass sendLdapQueryReq
Dump of assembler code for function SessionMt::sendLdapQueryReq(CallPartyNumber_t const*, bool):
0x0000000000b1ca40 <+0>: mov %rbp,-0x28(%rsp)
0x0000000000b1ca45 <+5>: mov %r15,-0x8(%rsp)
0x0000000000b1ca4a <+10>: mov %rdi,%rbp
0x0000000000b1ca4d <+13>: mov %rbx,-0x30(%rsp)
0x0000000000b1ca52 <+18>: mov %r12,-0x20(%rsp)
0x0000000000b1ca57 <+23>: mov %rsi,%r15
0x0000000000b1ca5a <+26>: mov %r13,-0x18(%rsp)
0x0000000000b1ca5f <+31>: mov %r14,-0x10(%rsp)
0x0000000000b1ca64 <+36>: sub $0x208,%rsp
0x0000000000b1ca6b <+43>: mov %fs:0x28,%rax
0x0000000000b1ca74 <+52>: mov %rax,0x1c8(%rsp)
0x0000000000b1ca7c <+60>: xor %eax,%eax
0x0000000000b1ca7e <+62>: mov %dl,0x93(%rsp)
0x0000000000b1ca85 <+69>: movl $0x2,0x1c4(%rsp)
0x0000000000b1ca90 <+80>: callq 0x1c2b406 <mxLog::GetInstance()>
0x0000000000b1ca95 <+85>: movzbl 0x8(%rax),%eax
0x0000000000b1ca99 <+89>: test %al,%al
0x0000000000b1ca9b <+91>: jne 0xb1cbb8 <SessionMt::sendLdapQueryReq(CallPartyNumber_t const*, bool)+376>
0x0000000000b1caa1 <+97>: lea 0x140(%rsp),%rdi
0x0000000000b1caa9 <+105>: callq 0x16f7570 <CcString::CcString()>
0x0000000000b1caae <+110>: mov 0xc8(%rbp),%rax
0x0000000000b1cab5 <+117>: lea 0x140(%rsp),%rcx
0x0000000000b1cabd <+125>: xor %edx,%edx
0x0000000000b1cabf <+127>: mov %r15,%rsi
0x0000000000b1cac2 <+130>: mov 0x28(%rax),%rax
0x0000000000b1cac6 <+134>: mov 0x58(%rax),%rdi
0x0000000000b1caca <+138>: callq 0x441110 <RmsDbMgr::getFormatedNumber(const CallPartyNumber_t *, ._2039, CcString &)>
=> 0x0000000000b1cacf <+143>: cmpq $0x0,0x150(%rsp)
0x0000000000b1cad8 <+152>: je 0xb1cb88 <SessionMt::sendLdapQueryReq(CallPartyNumber_t const*, bool)+328>
0x0000000000b1cade <+158>: movl $0x2,0x1c4(%rsp)
before calling RmsDbMgr::getFormatedNumber(), %rsi (2nd argument considering THIS as first) was set as %r15 which was 0x2cb90160, that was correct.
(gdb) p/x $r15
$9 = 0x2cb90160
and assembly of RmsDbMgr::getFormatedNumber() as below ...
(gdb) disass getFormatedNumber
Dump of assembler code for function RmsDbMgr::getFormatedNumber(const CallPartyNumber_t *, ._2039, CcString &):
0x0000000000441110 <+0>: mov %rbp,-0x28(%rsp)
0x0000000000441115 <+5>: mov %r13,-0x18(%rsp)
0x000000000044111a <+10>: mov %edx,%ebp
0x000000000044111c <+12>: mov %r14,-0x10(%rsp)
0x0000000000441121 <+17>: mov %r15,-0x8(%rsp)
0x0000000000441126 <+22>: mov %rdi,%r14
0x0000000000441129 <+25>: mov %rbx,-0x30(%rsp)
0x000000000044112e <+30>: mov %r12,-0x20(%rsp)
0x0000000000441133 <+35>: sub $0x178,%rsp
0x000000000044113a <+42>: mov %fs:0x28,%rax
0x0000000000441143 <+51>: mov %rax,0x138(%rsp)
0x000000000044114b <+59>: xor %eax,%eax
0x000000000044114d <+61>: test %rsi,%rsi
0x0000000000441150 <+64>: mov %rsi,%r13
0x0000000000441153 <+67>: mov %rcx,%r15
0x0000000000441156 <+70>: je 0x4411e0 <RmsDbMgr::getFormatedNumber(const CallPartyNumber_t *, ._2039, CcString &)+208>
0x000000000044115c <+76>: cmp $0x2,%edx
0x000000000044115f <+79>: jg 0x4411e0 <RmsDbMgr::getFormatedNumber(const CallPartyNumber_t *, ._2039, CcString &)+208>
0x0000000000441165 <+85>: lea 0x100(%rsp),%rdi
0x000000000044116d <+93>: callq 0x16f7570 <CcString::CcString()>
0x0000000000441172 <+98>: movzwl 0x53e74(%r14),%esi
0x000000000044117a <+106>: lea 0x100(%rsp),%rdi
0x0000000000441182 <+114>: callq 0x16f90e0 <CcString::operator+=(u16_t const)>
0x0000000000441187 <+119>: lea 0x8(%r13),%rsi
0x000000000044118b <+123>: mov %r15,%rdi
0x000000000044118e <+126>: callq 0x16facc0 <CcString::operator=(CcString const&)>
=> 0x0000000000441193 <+131>: movl $0x2,0x134(%rsp)
0x000000000044119e <+142>: callq 0x1c2b406 <mxLog::GetInstance()>
0x00000000004411a3 <+147>: movzbl 0x8(%rax),%eax
0x00000000004411a7 <+151>: test %al,%al
in RmsDbMgr::getFormatedNumber(), %r15 was saved at -0x8(%rsp) before sp moving up 0x178 bytes, and it was 0x2cb90160 too.
(gdb) x/a $rsp+0x178-0x8
0x47000aa0: 0x2cb90160
then before doing anything, %rsi was assigned to %r13, but now r13 had a different value which wrong.
(gdb) p/x $r13
$9 = 0xb90160
anyone can help to find out what's wrong with it?
I am trying to write a simple sum function in x86 assembly - to which i am passing 3 and 8 as arguments. However, the code doesn't print the sum. Appreciate any help in spotting the errors. I'm using NASM
section .text
global _start
_sum:
push ebp
mov ebp, esp
push edi
push esi ;prologue ends
mov eax, [ebp+8]
add eax, [ebp+12]
pop esi ;epilogue begins
pop edi
mov esp, ebp
pop ebp
ret 8
_start:
push 8
push 3
call _sum
mov edx, 1
mov ecx, eax
mov ebx, 1 ;stdout
mov eax, 4 ;write
int 0x80
mov ebx, 0
mov eax, 1 ;exit
int 0x80
To me, this looks like Linux assembler. From this page, in the Examples section, subsection int 0x80, it looks like ecx expects the address of the string:
_start:
movl $4, %eax ; use the write syscall
movl $1, %ebx ; write to stdout
movl $msg, %ecx ; use string "Hello World"
movl $12, %edx ; write 12 characters
int $0x80 ; make syscall
So, you'll have to get a spare chunk of memory, convert your result to a string, probably null-terminate that string, and then call the write with the address of the string in ecx.
For an example of how to convert an integer to a string see Printing an Int (or Int to String) You'll have to store each digit in a string instead of printing it, and null-terminate it. Then you can print the string.
Sorry, I have not programmed in assembly in years, so I cannot give you a more detailed answer, but hope that this will be enough to point you in the right direction.
This question already has answers here:
Closed 12 years ago.
Possible Duplicate:
Assembler mov issue
I have the next code:
mov ax,#data
mov ds,ax
Why I can not write just like this?
mov ds,#data
All source:
.MODEL small
.STACK 100h
.DATA
HelloMessage DB 'Hello, world',13,10,'$'
.CODE
.startup
mov ax,#data
mov ds,ax
mov ah,9
mov dx,OFFSET HelloMessage
int 21h
mov ah,4ch
int 21h
END
Thank you!
You can't move directly #data in ds because you can't assign directly a segment to ds. You are allowed to move a register with the value of the segment you want to move in ds.