how to tell the difference between lc3 opcodes and lc3 processor directives












0















I've been learning lc3 and I'm writing a disassembler. I have a question about how, when reading assembled lc3 code, to tell the difference between an opcode and a processor directive (for example, a .FILL directive).



Now, LC3 instructions are 16 bits wide. Here's an example:



0000100000000111


This example is a BR (branch) instruction. The first 4 numbers from the left (0000) indicate this is a BR opcode, and the 3 numbers after, (100) are the conditions to test (negative, zero, and positive, in that order. So 100 means test for negative only, 110 would mean test for negative or zero, etc). If none of these three bits are set, then this is in fact, not a BR instruction, but instead it is a processor directive. So the following:



0000000001001001


the first 4 from the left numbers are 0000, so normally this would be a BR instruction, but because none of the Neg, Zero, Pos bits are set, then it is instead a .FILL processor directive, meaning that all 16 bits are instead computed into one hex number, in this case 0x0049.



Now this is just one of 16 opcodes. I also happen to know that the opcode for TRAP instructions (1111) has a similar special case, ie if ANY of the same three bits (plus one more to the right) are set, then it is not a TRAP instruction. Now, since opcode 0000 and opcode 1111 have these special cases, it makes sense that the opcodes in between should have special cases like this too. But I've gone through all documentation that I can find, and nowhere seems to mention these cases (although, I know that I'm right from reading the .lst files produced by lc3 assembler). Does anyone know of any documentation that mentions this? Or does anyone know of any more of these 'special cases'? Thanks



EDIT:
Thanks for your reply, but I'm still not sure how I can tell the difference between an instruction and data. Here are a few lines I just copied from a .lst file:



(305A) 0059  0000000001011001 (  45)                 .FILL x0059
(305B) 0000 0000000000000000 ( 45) .FILL x0000
(305C) FFD0 1111111111010000 ( 46) RESET .FILL xFFD0
(305D) 0045 0000000001000101 ( 47) LINE1 .FILL x0045


Notice that the first two lines and the last lines could easily be read as BR instructions if it wasn't for the fact that none of the NZP bits are set. And the same goes for the 3rd line and TRAP instructions. So, what about this:



0101001001100000   ;; or 0x5260


Is this an AND instruction or is it a .FILL directive? How to tell?










share|improve this question

























  • Powerful disassemblers like IDA Pro do analysis of which locations can never be in a flow of execution and then treat these locations as data values rather than trying to interpret them as opcodes.

    – barny
    Nov 21 '18 at 18:49











  • A .FILL pseudo op can go anywhere though, so I don't see how I could test this. I have made a working disassembler, the link is in the question, but i worry that certain special cases could cause it to output incorrect info

    – box04057934
    Nov 21 '18 at 18:59
















0















I've been learning lc3 and I'm writing a disassembler. I have a question about how, when reading assembled lc3 code, to tell the difference between an opcode and a processor directive (for example, a .FILL directive).



Now, LC3 instructions are 16 bits wide. Here's an example:



0000100000000111


This example is a BR (branch) instruction. The first 4 numbers from the left (0000) indicate this is a BR opcode, and the 3 numbers after, (100) are the conditions to test (negative, zero, and positive, in that order. So 100 means test for negative only, 110 would mean test for negative or zero, etc). If none of these three bits are set, then this is in fact, not a BR instruction, but instead it is a processor directive. So the following:



0000000001001001


the first 4 from the left numbers are 0000, so normally this would be a BR instruction, but because none of the Neg, Zero, Pos bits are set, then it is instead a .FILL processor directive, meaning that all 16 bits are instead computed into one hex number, in this case 0x0049.



Now this is just one of 16 opcodes. I also happen to know that the opcode for TRAP instructions (1111) has a similar special case, ie if ANY of the same three bits (plus one more to the right) are set, then it is not a TRAP instruction. Now, since opcode 0000 and opcode 1111 have these special cases, it makes sense that the opcodes in between should have special cases like this too. But I've gone through all documentation that I can find, and nowhere seems to mention these cases (although, I know that I'm right from reading the .lst files produced by lc3 assembler). Does anyone know of any documentation that mentions this? Or does anyone know of any more of these 'special cases'? Thanks



EDIT:
Thanks for your reply, but I'm still not sure how I can tell the difference between an instruction and data. Here are a few lines I just copied from a .lst file:



(305A) 0059  0000000001011001 (  45)                 .FILL x0059
(305B) 0000 0000000000000000 ( 45) .FILL x0000
(305C) FFD0 1111111111010000 ( 46) RESET .FILL xFFD0
(305D) 0045 0000000001000101 ( 47) LINE1 .FILL x0045


Notice that the first two lines and the last lines could easily be read as BR instructions if it wasn't for the fact that none of the NZP bits are set. And the same goes for the 3rd line and TRAP instructions. So, what about this:



0101001001100000   ;; or 0x5260


Is this an AND instruction or is it a .FILL directive? How to tell?










share|improve this question

























  • Powerful disassemblers like IDA Pro do analysis of which locations can never be in a flow of execution and then treat these locations as data values rather than trying to interpret them as opcodes.

    – barny
    Nov 21 '18 at 18:49











  • A .FILL pseudo op can go anywhere though, so I don't see how I could test this. I have made a working disassembler, the link is in the question, but i worry that certain special cases could cause it to output incorrect info

    – box04057934
    Nov 21 '18 at 18:59














0












0








0








I've been learning lc3 and I'm writing a disassembler. I have a question about how, when reading assembled lc3 code, to tell the difference between an opcode and a processor directive (for example, a .FILL directive).



Now, LC3 instructions are 16 bits wide. Here's an example:



0000100000000111


This example is a BR (branch) instruction. The first 4 numbers from the left (0000) indicate this is a BR opcode, and the 3 numbers after, (100) are the conditions to test (negative, zero, and positive, in that order. So 100 means test for negative only, 110 would mean test for negative or zero, etc). If none of these three bits are set, then this is in fact, not a BR instruction, but instead it is a processor directive. So the following:



0000000001001001


the first 4 from the left numbers are 0000, so normally this would be a BR instruction, but because none of the Neg, Zero, Pos bits are set, then it is instead a .FILL processor directive, meaning that all 16 bits are instead computed into one hex number, in this case 0x0049.



Now this is just one of 16 opcodes. I also happen to know that the opcode for TRAP instructions (1111) has a similar special case, ie if ANY of the same three bits (plus one more to the right) are set, then it is not a TRAP instruction. Now, since opcode 0000 and opcode 1111 have these special cases, it makes sense that the opcodes in between should have special cases like this too. But I've gone through all documentation that I can find, and nowhere seems to mention these cases (although, I know that I'm right from reading the .lst files produced by lc3 assembler). Does anyone know of any documentation that mentions this? Or does anyone know of any more of these 'special cases'? Thanks



EDIT:
Thanks for your reply, but I'm still not sure how I can tell the difference between an instruction and data. Here are a few lines I just copied from a .lst file:



(305A) 0059  0000000001011001 (  45)                 .FILL x0059
(305B) 0000 0000000000000000 ( 45) .FILL x0000
(305C) FFD0 1111111111010000 ( 46) RESET .FILL xFFD0
(305D) 0045 0000000001000101 ( 47) LINE1 .FILL x0045


Notice that the first two lines and the last lines could easily be read as BR instructions if it wasn't for the fact that none of the NZP bits are set. And the same goes for the 3rd line and TRAP instructions. So, what about this:



0101001001100000   ;; or 0x5260


Is this an AND instruction or is it a .FILL directive? How to tell?










share|improve this question
















I've been learning lc3 and I'm writing a disassembler. I have a question about how, when reading assembled lc3 code, to tell the difference between an opcode and a processor directive (for example, a .FILL directive).



Now, LC3 instructions are 16 bits wide. Here's an example:



0000100000000111


This example is a BR (branch) instruction. The first 4 numbers from the left (0000) indicate this is a BR opcode, and the 3 numbers after, (100) are the conditions to test (negative, zero, and positive, in that order. So 100 means test for negative only, 110 would mean test for negative or zero, etc). If none of these three bits are set, then this is in fact, not a BR instruction, but instead it is a processor directive. So the following:



0000000001001001


the first 4 from the left numbers are 0000, so normally this would be a BR instruction, but because none of the Neg, Zero, Pos bits are set, then it is instead a .FILL processor directive, meaning that all 16 bits are instead computed into one hex number, in this case 0x0049.



Now this is just one of 16 opcodes. I also happen to know that the opcode for TRAP instructions (1111) has a similar special case, ie if ANY of the same three bits (plus one more to the right) are set, then it is not a TRAP instruction. Now, since opcode 0000 and opcode 1111 have these special cases, it makes sense that the opcodes in between should have special cases like this too. But I've gone through all documentation that I can find, and nowhere seems to mention these cases (although, I know that I'm right from reading the .lst files produced by lc3 assembler). Does anyone know of any documentation that mentions this? Or does anyone know of any more of these 'special cases'? Thanks



EDIT:
Thanks for your reply, but I'm still not sure how I can tell the difference between an instruction and data. Here are a few lines I just copied from a .lst file:



(305A) 0059  0000000001011001 (  45)                 .FILL x0059
(305B) 0000 0000000000000000 ( 45) .FILL x0000
(305C) FFD0 1111111111010000 ( 46) RESET .FILL xFFD0
(305D) 0045 0000000001000101 ( 47) LINE1 .FILL x0045


Notice that the first two lines and the last lines could easily be read as BR instructions if it wasn't for the fact that none of the NZP bits are set. And the same goes for the 3rd line and TRAP instructions. So, what about this:



0101001001100000   ;; or 0x5260


Is this an AND instruction or is it a .FILL directive? How to tell?







assembly disassembly lc3






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited Nov 21 '18 at 18:43







box04057934

















asked Nov 21 '18 at 18:20









box04057934box04057934

84




84













  • Powerful disassemblers like IDA Pro do analysis of which locations can never be in a flow of execution and then treat these locations as data values rather than trying to interpret them as opcodes.

    – barny
    Nov 21 '18 at 18:49











  • A .FILL pseudo op can go anywhere though, so I don't see how I could test this. I have made a working disassembler, the link is in the question, but i worry that certain special cases could cause it to output incorrect info

    – box04057934
    Nov 21 '18 at 18:59



















  • Powerful disassemblers like IDA Pro do analysis of which locations can never be in a flow of execution and then treat these locations as data values rather than trying to interpret them as opcodes.

    – barny
    Nov 21 '18 at 18:49











  • A .FILL pseudo op can go anywhere though, so I don't see how I could test this. I have made a working disassembler, the link is in the question, but i worry that certain special cases could cause it to output incorrect info

    – box04057934
    Nov 21 '18 at 18:59

















Powerful disassemblers like IDA Pro do analysis of which locations can never be in a flow of execution and then treat these locations as data values rather than trying to interpret them as opcodes.

– barny
Nov 21 '18 at 18:49





Powerful disassemblers like IDA Pro do analysis of which locations can never be in a flow of execution and then treat these locations as data values rather than trying to interpret them as opcodes.

– barny
Nov 21 '18 at 18:49













A .FILL pseudo op can go anywhere though, so I don't see how I could test this. I have made a working disassembler, the link is in the question, but i worry that certain special cases could cause it to output incorrect info

– box04057934
Nov 21 '18 at 18:59





A .FILL pseudo op can go anywhere though, so I don't see how I could test this. I have made a working disassembler, the link is in the question, but i worry that certain special cases could cause it to output incorrect info

– box04057934
Nov 21 '18 at 18:59












1 Answer
1






active

oldest

votes


















0














.FILL can emit arbitrary bytes into the output file.



There's literally no difference in the machine code between manually encoding an instruction and emitting it with .fill vs. letting the assembler encode it from a mnemonic + operands. See How to avoid executing variables in lc3 assembly for an example.



When the CPU is decoding / executing machine code, it doesn't care how the bytes got there, it just treats them as instructions. Your disassembler should do the same.



If you encounter an instruction word that isn't a valid LC-3 instruction, you might simply disassemble it as .fill 0x1234 or something, then move on to the next word. This is what existing disassemblers do for ISAs like ARM and x86.






share|improve this answer























    Your Answer






    StackExchange.ifUsing("editor", function () {
    StackExchange.using("externalEditor", function () {
    StackExchange.using("snippets", function () {
    StackExchange.snippets.init();
    });
    });
    }, "code-snippets");

    StackExchange.ready(function() {
    var channelOptions = {
    tags: "".split(" "),
    id: "1"
    };
    initTagRenderer("".split(" "), "".split(" "), channelOptions);

    StackExchange.using("externalEditor", function() {
    // Have to fire editor after snippets, if snippets enabled
    if (StackExchange.settings.snippets.snippetsEnabled) {
    StackExchange.using("snippets", function() {
    createEditor();
    });
    }
    else {
    createEditor();
    }
    });

    function createEditor() {
    StackExchange.prepareEditor({
    heartbeatType: 'answer',
    autoActivateHeartbeat: false,
    convertImagesToLinks: true,
    noModals: true,
    showLowRepImageUploadWarning: true,
    reputationToPostImages: 10,
    bindNavPrevention: true,
    postfix: "",
    imageUploader: {
    brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
    contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
    allowUrls: true
    },
    onDemand: true,
    discardSelector: ".discard-answer"
    ,immediatelyShowMarkdownHelp:true
    });


    }
    });














    draft saved

    draft discarded


















    StackExchange.ready(
    function () {
    StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53418312%2fhow-to-tell-the-difference-between-lc3-opcodes-and-lc3-processor-directives%23new-answer', 'question_page');
    }
    );

    Post as a guest















    Required, but never shown

























    1 Answer
    1






    active

    oldest

    votes








    1 Answer
    1






    active

    oldest

    votes









    active

    oldest

    votes






    active

    oldest

    votes









    0














    .FILL can emit arbitrary bytes into the output file.



    There's literally no difference in the machine code between manually encoding an instruction and emitting it with .fill vs. letting the assembler encode it from a mnemonic + operands. See How to avoid executing variables in lc3 assembly for an example.



    When the CPU is decoding / executing machine code, it doesn't care how the bytes got there, it just treats them as instructions. Your disassembler should do the same.



    If you encounter an instruction word that isn't a valid LC-3 instruction, you might simply disassemble it as .fill 0x1234 or something, then move on to the next word. This is what existing disassemblers do for ISAs like ARM and x86.






    share|improve this answer




























      0














      .FILL can emit arbitrary bytes into the output file.



      There's literally no difference in the machine code between manually encoding an instruction and emitting it with .fill vs. letting the assembler encode it from a mnemonic + operands. See How to avoid executing variables in lc3 assembly for an example.



      When the CPU is decoding / executing machine code, it doesn't care how the bytes got there, it just treats them as instructions. Your disassembler should do the same.



      If you encounter an instruction word that isn't a valid LC-3 instruction, you might simply disassemble it as .fill 0x1234 or something, then move on to the next word. This is what existing disassemblers do for ISAs like ARM and x86.






      share|improve this answer


























        0












        0








        0







        .FILL can emit arbitrary bytes into the output file.



        There's literally no difference in the machine code between manually encoding an instruction and emitting it with .fill vs. letting the assembler encode it from a mnemonic + operands. See How to avoid executing variables in lc3 assembly for an example.



        When the CPU is decoding / executing machine code, it doesn't care how the bytes got there, it just treats them as instructions. Your disassembler should do the same.



        If you encounter an instruction word that isn't a valid LC-3 instruction, you might simply disassemble it as .fill 0x1234 or something, then move on to the next word. This is what existing disassemblers do for ISAs like ARM and x86.






        share|improve this answer













        .FILL can emit arbitrary bytes into the output file.



        There's literally no difference in the machine code between manually encoding an instruction and emitting it with .fill vs. letting the assembler encode it from a mnemonic + operands. See How to avoid executing variables in lc3 assembly for an example.



        When the CPU is decoding / executing machine code, it doesn't care how the bytes got there, it just treats them as instructions. Your disassembler should do the same.



        If you encounter an instruction word that isn't a valid LC-3 instruction, you might simply disassemble it as .fill 0x1234 or something, then move on to the next word. This is what existing disassemblers do for ISAs like ARM and x86.







        share|improve this answer












        share|improve this answer



        share|improve this answer










        answered Nov 21 '18 at 18:31









        Peter CordesPeter Cordes

        122k17184312




        122k17184312






























            draft saved

            draft discarded




















































            Thanks for contributing an answer to Stack Overflow!


            • Please be sure to answer the question. Provide details and share your research!

            But avoid



            • Asking for help, clarification, or responding to other answers.

            • Making statements based on opinion; back them up with references or personal experience.


            To learn more, see our tips on writing great answers.




            draft saved


            draft discarded














            StackExchange.ready(
            function () {
            StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53418312%2fhow-to-tell-the-difference-between-lc3-opcodes-and-lc3-processor-directives%23new-answer', 'question_page');
            }
            );

            Post as a guest















            Required, but never shown





















































            Required, but never shown














            Required, but never shown












            Required, but never shown







            Required, but never shown

































            Required, but never shown














            Required, but never shown












            Required, but never shown







            Required, but never shown







            Popular posts from this blog

            Costa Masnaga

            Fotorealismo

            Sidney Franklin