9 ms·
Impressive. Is there a reason to jump over the string instead of just having the string after the program? Seems like one could save two bytes doing that.
by colejohnson66 4y ago
Impressive. Is there a reason to jump over the string instead of just having the string after the program? Seems like one could save two bytes doing that.
- donio 4y agodebug.exe is single pass and doesn't do labels so by having the string first you know its address later.
- vore 4y agoYou can compute the address of the string yourself like a two-pass assembler would, though, so that shouldn't be limiting.
- Agingcoder 4y agoThe COM executable gets loaded by DOS at address 100h, so the first bytes have to be executable code, if memory serves me well?
- vore 4y agoI think OP is saying what if you wrote it as: mov ah, 9 mov dx, offset helloworld int 21 mov ah, 0 int 21 .helloworld: db 'hello, world', d, A, '$'
- dmitrygr 4y agoYou are right and sister comment to this one is wrong. Thusly: MOV AH, 9 MOV DX, str INT 21 MOV AH, 0 INT 21 Str: DB 'hello, world', d, A, '$'
- q-big 4y agoThis program can be simplified further: MOV AH, 9 MOV DX, str INT 21 RET str: DB 'hello, world', d, A, '$' Why can MOV AH, 0 INT 21 be replaced by RET? Here is the answer: https://stackoverflow.com/a/60805758 https://stackoverflow.com/a/60805758 UPDATE: Under https://news.ycombinator.com/item?id=33398592 https://news.ycombinator.com/item?id=33398592 userbinator posted an additional possible optimization.
- ralferoo 4y agoNot a size optimisation, but a performance optimisation... INT 21 RET can be replaced with JP 5
- blueflow 4y agoThat mnemonic would be "JMP" on x86. At address 5 in the PSP is the CP/M-style syscall entry point, it is not advised to not use it because it relies on the A20 line being short-circuited to zero, which cannot be relied on in later MS-DOS versions. I don't see why this would be faster than using RET directly and having the INT 20 opcode at address 0 do the work.
- jart 4y agoJump parity? But according to http://www.fysnet.net/yourhelp.htm http://www.fysnet.net/yourhelp.htm the parity flag is only set in DOS 7.1+
- susam 4y agoI wrote this about 20 years ago during my university days. I happened to stumble upon it today in my archives and thought of sharing it on GitHub. I was still learning microprocessors back then. While browsing the C:\Windows directory, I fortuitously happened to discover the DEBUG.EXE program. Turned out it was available on any standard installation of MS-DOS as well as Windows 98. That chance encounter helped me to dive into the world of assembly language programming much before the coursework introduced me to more popular assemblers. Since I was still learning the x86 CPUs, the intention here was not to save bytes but instead to have something working. I believe I picked up the style of having the string at the top and jumping over it from other similar code I had come across in those days. You are right of course. Here is a complete example that moves the string to the bottom and saves two bytes: C:\>DEBUG -A 1165:0100 MOV AH, 9 1165:0102 MOV DX, 10B 1165:0105 INT 21 1165:0107 MOV AH, 0 1165:0109 INT 21 1165:010B DB 'hello, world', D, A, '$' 1165:011A -G hello, world Program terminated normally -N HELLO.COM -R CX CX 0000 :1A -W Writing 0001A bytes -Q C:\>HELLO hello, world C:\> I have now updated the GitHub repository with this updated source code and binary. Thank you for the nice comment!
- owl57 4y agoCurious. These other programmers probably learned the habit from some even older code. Jumping over data isn't a very obvious way of organising code, so probably it served some purpose many years ago. Maybe someone here knows what was that purpose?
- deleted 4y ago[deleted]
- userbinator 4y agoI remember seeing that in old Asm books too. My best guess is that it avoids having too many forward references, which would take up precious memory in the systems of the time and perhaps reach the limit of the assembler sooner.
- _the_inflator 4y ago
- pizza234 4y agoThis is an ASM program with a very standard structure (including the standard printing API: http://spike.scu.edu.au/~barry/interrupts.html#ah09 http://spike.scu.edu.au/~barry/interrupts.html#ah09) using a very standard tool (DEBUG.exe, common at the time for quick debugging); I'm confused why this is impressive.
- alrlroipsp 4y agoMost if not all ANCIENT assembers did a 1-pass translation of input source and thus would not recognize tokens that was referenced but not yet declared. Hence you declare your variables at the start of the program and jump past them.
- rep_lodsb 4y agoAny "real" assembler has to support forward references, otherwise you couldn't even jump past the initial data section, except by using an absolute address! Minimizing the number of forward references may make the assembly run faster or use less memory, but usually it's just a convention to make the source code more neatly organized.